你如何遍历Golang结构中的字段以获取和设置值的可扩展方式? [英] How do you loop through the fields in a Golang struct to get and set values in an extensible way?
问题描述
类型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
}
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 }
我在那里一半,但仍然不能扩展到我想要利用这个更新功能的所有结构。
**其他有用的链接**
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}
http://play.golang.org/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:
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}
http://play.golang.org/p/UKFMBxfbZD
这篇关于你如何遍历Golang结构中的字段以获取和设置值的可扩展方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!