为了账号安全,请及时绑定邮箱和手机立即绑定

以编程方式填充 golang 结构

以编程方式填充 golang 结构

Go
森栏 2023-07-31 15:39:23
我有一个包含多种类型数据记录的文件,我需要将其解析为结构。我很高兴了解一种按记录类型填充结构的惯用方法(如果存在)。类似于 python 的namedtuple(*fields)构造函数。package mainimport (    "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~5BDY~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可以方便地用代码替换,也许是某种允许结构本身处理类型转换的通用解码器。
查看完整描述

1 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

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

必须导出一个字段才能由反射包设置。通过将名称中的第一个符文大写来导出名称:

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:


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;应用程序忽略解析整数返回的错误;如果数据中的字段多于结构体,应用程序将会出现恐慌;当应用程序遇到不支持的字段类型时,不会报告错误;和更多。


在 Go Playground 上运行它



查看完整回答
反对 回复 2023-07-31
  • 1 回答
  • 0 关注
  • 130 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信