然后我有这个结构的两个实例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结构中的字段以获取和设置值的可扩展方式?
发布评论