你如何遍历Golang结构中的字段以获取和设置值的可扩展方式?

编程入门 行业动态 更新时间:2024-10-24 14:22:49
本文介绍了你如何遍历Golang结构中的字段以获取和设置值的可扩展方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

类型Person结构{名字字符串姓氏字符串年uint8 }

然后我有这个结构的两个实例PersonA和PersonB。

PersonA:= {,Obama,6} PersonB:= {President ,Carter,8}

我想写一个函数将PersonA中的值复制到PersonB给每个领域一些条件(即非空)。我知道如何通过硬编码字段名来完成此任务,但是我想要一个即使更改Person结构也能正常工作的函数。

我知道Go反射是有帮助的,但问题在于如何设置值需要知道类型,如果您想使用SetInt之类的东西。但是,有没有一种简单的方法来做到这一点?

** Javascript类比** 在Javascript中,您可以对someObject中的属性进行循环。

(对于persona中的propt){ if personA [propt]!={ //做某事 personB [propt] = personA [propt] } }

我排除的选项:

  • 跟踪地图中每个结构中的字段,然后在反映pkg 中使用FieldByName和Set *函数集合的组合。

  • 手动创建一个通过Person字段的循环(下图)。因为我想为许多其他结构(学校,动物等等)做这种类型的更新。

    if PersonA.Firstname!={ PersonB.Firstname = PersonA.Firstname }

    ...

    if PersonA.Years!={ PersonB.Years = PersonA.Years }

  • 我在那里一半,但仍然不能扩展到我想要利用这个更新功能的所有结构。

    **其他有用的链接** GoLang:按名称访问结构属性

    解决方案

    以下是解决方案 f2.Set(reflect.Value(f))是关键这里

    package main import(fmt反映) func main(){ type T struct { A int B string } t:= T {23,skidoo} t2:= T {} s:= reflect.ValueOf(& t).Elem() s2:= reflect。 ValueOf(& t2).Elem() typeOfT:= s.Type() fmt.Println(t =,t) fmt.Println(t2 =, t2) for i:= 0;我< s.NumField(); i ++ {f:= s.Field(i) f2:= s2.Field(i) fmt.Printf(%d:%s%s =%v \\\ ,i, typeOfT.Field(i).Name,f.Type(),f.Interface()) fmt.Printf(%d:%s%s =%v \\\ ,i, typeOfT.Field(i).Name,f2.Type(),f2.Interface()) f2.Set(reflect.Value(f)) fmt。 printf(%d:%s%s =%v \ n,i, typeOfT.Field(i).Name,f2.Type(),f2.Interface()) fmt.Println(t =,t) fmt.Println(t2 =,t2)} 输出: t = {23 skidoo} t2 = {0} 0:A int = 23 0:A int = 0 0:A int = 23 1:B string = skidoo 1:B string = 1:B string = skidoo t = {23 skidoo} t2 = {23 skidoo}

    play.golang/p/UKFMBxfbZD

    I have a struct Person.

    type Person struct { Firstname string Lastname string Years uint8 }

    Then I have two instances of this struct, PersonA and PersonB.

    PersonA := {"", "Obama", 6} PersonB := {"President", "Carter", 8}

    I want to write a function that copies the values from PersonA to PersonB given some condition for each field (i.e. non-empty). I know how to do this by hard-coding the field names, but I want a function that works even if I change the Person struct.

    I know Go reflections is helpful, but the issue is getting and setting the values requires knowing the types, if you want to use something like SetInt. But is there is a "simple" way to do this?

    ** Javascript analogy ** In Javascript, you could just do a (for property in someObject) to loop through.

    (for propt in personA) { if personA[propt] != "" { // do something personB[propt] = personA[propt] } }

    Options I've ruled out:

  • Keeping track of the fields in each struct in a map, then using a combination of FieldByName and the collection of Set* functions in the reflect pkg.

  • Creating a loop through the fields of Person manually (below). Because I want to do this type of "update" for many other structs (School, Animals, etc...)

    if PersonA.Firstname != "" { PersonB.Firstname = PersonA.Firstname }

    ...

    if PersonA.Years != "" { PersonB.Years = PersonA.Years }

  • The question below gets me half-way there, but still isn't extensible to all structs for which I want to utilize this "update" function.

    in golang, using reflect, how do you set the value of a struct field?

    ** Other Helpful Links ** GoLang: Access struct property by name

    解决方案

    Here is the solution f2.Set(reflect.Value(f)) is the key here

    package main import ( "fmt" "reflect" ) func main() { type T struct { A int B string } t := T{23, "skidoo"} t2:= T{} s := reflect.ValueOf(&t).Elem() s2 := reflect.ValueOf(&t2).Elem() typeOfT := s.Type() fmt.Println("t=",t) fmt.Println("t2=",t2) for i := 0; i < s.NumField(); i++ { f := s.Field(i) f2:= s2.Field(i) fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface()) fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f2.Type(), f2.Interface()) f2.Set(reflect.Value(f)) fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f2.Type(), f2.Interface()) } fmt.Println("t=",t) fmt.Println("t2=",t2) } Output: t= {23 skidoo} t2= {0 } 0: A int = 23 0: A int = 0 0: A int = 23 1: B string = skidoo 1: B string = 1: B string = skidoo t= {23 skidoo} t2= {23 skidoo}

    play.golang/p/UKFMBxfbZD

    更多推荐

    你如何遍历Golang结构中的字段以获取和设置值的可扩展方式?

    本文发布于:2023-07-30 00:40:17,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1245018.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:遍历   字段   结构   方式   Golang

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!