gpt4 book ai didi

go - 以编程方式填充 golang 结构

转载 作者:行者123 更新时间:2023-12-01 21:23:46 24 4
gpt4 key购买 nike

我有一个包含多种类型数据记录的文件,我需要将其解析为结构。

我会很感激学习一种惯用的方式——如果存在的话——按记录类型填充结构。类似于 python 的 namedtuple(*fields)构造函数。

package main

import (
"fmt"
"strconv"
"strings"
)

type X interface{}

type HDR struct {
typer, a string
b int
}

type BDY struct {
typer, c string
d int
e string
}

var lines string = `HDR~two~5
BDY~four~6~five`

func sn(s string) int {
i, _ := strconv.Atoi(s)
return i
}

func main() {
sl := strings.Split(lines, "\n")
for _, l := range sl {
fields := strings.Split(l, "~")
var r X
switch fields[0] {
case "HDR":
r = HDR{fields[0], fields[1], sn(fields[2])} // 1
case "BDY":
r = BDY{fields[0], fields[1], sn(fields[2]), fields[3]} // 2
}
fmt.Printf("%T : %v\n", r, r)
}
}

我特别有兴趣了解标记为 // 1 的行。和 // 2可以方便地用代码替换,也许是某种通用解码器,它允许结构本身处理类型转换。

最佳答案

使用 reflect包以编程方式设置字段。

字段必须是 exported由反射包设置。通过将名称中的第一个 rune 大写来导出名称:

type HDR struct {
Typer, A string
B int
}

type BDY struct {
Typer, C string
D int
E string
}

创建名称映射到与名称关联的类型:
var types = map[string]reflect.Type{
"HDR": reflect.TypeOf((*HDR)(nil)).Elem(),
"BDY": reflect.TypeOf((*BDY)(nil)).Elem(),
}

对于每一行,使用 types 创建一个类型的值 map :
for _, l := range strings.Split(lines, "\n") {
fields := strings.Split(l, "~")
t := types[fields[0]]
v := reflect.New(t).Elem()
...
}

循环遍历该行中的字段。获取字段值,将字符串转换为字段值的种类并设置字段值:
    for i, f := range fields {
fv := v.Field(i)
switch fv.Type().Kind() {
case reflect.String:
fv.SetString(f)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
n, _ := strconv.ParseInt(f, 10, fv.Type().Bits())
fv.SetInt(n)
}
}

这是该方法的基本概述。错误处理明显缺失:如果类型名称不是 types 中提到的类型之一,应用程序将崩溃。 ;应用程序忽略解析整数返回的错误;如果数据中的字段多于结构,应用程序将崩溃;应用程序在遇到不受支持的字段种类时不会报告错误;和更多。

Run it on the Go Playground .

关于go - 以编程方式填充 golang 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58495137/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com