登录
首页 >  Golang >  Go问答

使用编程语言填充 golang 结构

来源:stackoverflow

时间:2024-02-29 16:51:24 271浏览 收藏

大家好,我们又见面了啊~本文《使用编程语言填充 golang 结构》的内容中将会涉及到等等。如果你正在学习Golang相关知识,欢迎关注我,以后会给大家带来更多Golang相关文章,希望我们能一起进步!下面就开始本文的正式内容~

问题内容

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

如果能了解一种按记录类型填充结构的惯用方式(如果存在的话),我将不胜感激。类似于 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 才能由反射包设置。通过将名称中的第一个符文大写来导出名称:

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

Run it on the Go Playground

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>