登录
首页 >  Golang >  Go问答

分配结构字段时如何按顺序从值数组中获取值?

来源:stackoverflow

时间:2024-02-14 09:45:22 188浏览 收藏

Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《分配结构字段时如何按顺序从值数组中获取值?》带大家来了解一下##content_title##,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发!


问题内容

我知道您可以使用文字创建一个结构,按顺序列出字段:

type Foo struct {
    A string 
    B string
    C string 
}

foo := Foo{ "foo", "bar", "baz" }

有什么方法可以动态地做同样的事情吗?我有一个值数组(实际上是一个数组数组),我想将它们按字段顺序分配给一个结构体数组,并且字段数量超过三个。有没有办法说“按顺序从这个值数组分配这个结构的字段”?我实在不想写一堆 structarray[i].field1 = dataarray[i][0]; structarray[i].field2 = dataarray[i][1]

到目前为止,我的想法是使用 reflect,这似乎太过分了,或者可能创建一个字段名称数组并构建 json 字符串并解组它们。还有更好的想法吗?


正确答案


通过反射,您可以编写如下函数:

func populate(dst any, src any) {
    v := reflect.valueof(dst)
    if v.type().kind() != reflect.pointer {
        panic("dst must be a pointer")
    }
    v = v.elem()
    if v.type().kind() != reflect.struct {
        panic("dst must be a pointer to struct")
    } 

    w := reflect.valueof(src)
    if w.type().kind() != reflect.slice {
        panic("src must be a slice")
    }
    for i := 0; i < v.numfield(); i++ {
        // in case you need to support source slices of arbitrary types
        value := w.index(i)
        if value.type().kind() == reflect.interface {
            value = value.elem()
        }
        v.field(i).set(value)
    }
}

您必须确保 dst 是可寻址的,因此将指向 foo 的指针传递给 populate;并且源切片中的第 i 个元素实际上可以分配给结构中相应的第 i 个字段。

上面的代码是相当简化的形式。您可以向其添加额外的检查,例如如果您认为调用者可能行为不当,请使用 canaddrassignableto

这样称呼它:

func main() {
    f := Foo{}
    populate(&f, []string{"foo", "bar", "baz"})
    fmt.Println(f) // {foo bar baz}
}

这里有一个演示,还显示您可以传递 []any 的切片作为源切片,以防结构字段的类型不同:https://go.dev/play/p/G8qjDCt79C7

今天关于《分配结构字段时如何按顺序从值数组中获取值?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

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