基本上,迭代a字段值的唯一方法(我知道)struct是这样的:
type Example struct {
a_number uint32
a_string string
}
//...
r := &Example{(2 << 31) - 1, "...."}:
for _, d:= range []interface{}{ r.a_number, r.a_string, } {
//do something with the d
}
Run Code Online (Sandbox Code Playgroud)
我想知道,如果有更好,更通用的实现方式[]interface{}{ r.a_number, r.a_string, },所以我不需要单独列出每个参数,或者,是否有更好的方法来循环结构?
我试图透过reflect包裹看,但是我碰了一堵墙,因为我不知道一旦取回就该做什么reflect.ValueOf(*r).Field(0).
谢谢!
nem*_*emo 98
使用后检索reflect.Value字段后,Field(i)可以通过调用从中获取接口值Interface().然后,所述界面值表示该字段的值.
没有功能可以将字段的值转换为具体类型,因为您可能知道,go中没有泛型.因此,不存在与签名没有功能GetValue() T
与T被该字段(其改变,当然,这取决于字段)的类型.
你可以实现的最接近的是GetValue() interface{},这正是reflect.Value.Interface()
提供的.
以下代码说明了如何使用反射(播放)获取结构中每个导出字段的值:
import (
"fmt"
"reflect"
)
func main() {
x := struct{Foo string; Bar int }{"foo", 2}
v := reflect.ValueOf(x)
values := make([]interface{}, v.NumField())
for i := 0; i < v.NumField(); i++ {
values[i] = v.Field(i).Interface()
}
fmt.Println(values)
}
Run Code Online (Sandbox Code Playgroud)
小智 60
如果您想遍历结构的字段和值,则可以使用以下 Go 代码作为参考。
package main
import (
"fmt"
"reflect"
)
type Student struct {
Fname string
Lname string
City string
Mobile int64
}
func main() {
s := Student{"Chetan", "Kumar", "Bangalore", 7777777777}
v := reflect.ValueOf(s)
typeOfS := v.Type()
for i := 0; i< v.NumField(); i++ {
fmt.Printf("Field: %s\tValue: %v\n", typeOfS.Field(i).Name, v.Field(i).Interface())
}
}
Run Code Online (Sandbox Code Playgroud)
在操场上奔跑
注意:如果您的结构中的字段未导出,v.Field(i).Interface()则会导致恐慌panic: reflect.Value.Interface: cannot return value obtained from unexported field or method.
也许为时已晚:))) 但是还有另一种解决方案,您可以找到结构的键和值并对其进行迭代
package main
import (
"fmt"
"reflect"
)
type person struct {
firsName string
lastName string
iceCream []string
}
func main() {
u := struct {
myMap map[int]int
mySlice []string
myPerson person
}{
myMap: map[int]int{1: 10, 2: 20},
mySlice: []string{"red", "green"},
myPerson: person{
firsName: "Esmaeil",
lastName: "Abedi",
iceCream: []string{"Vanilla", "chocolate"},
},
}
v := reflect.ValueOf(u)
for i := 0; i < v.NumField(); i++ {
fmt.Println(v.Type().Field(i).Name)
fmt.Println("\t", v.Field(i))
}
}
Run Code Online (Sandbox Code Playgroud)
and there is no *panic* for v.Field(i)
Run Code Online (Sandbox Code Playgroud)
Go 1.17(2021 年第三季度)应该添加一个新选项,通过提交 009bfea和CL 281233修复问题 42782。
反映:添加 VisibleFields 功能
在编写反映结构类型的代码时,通常需要了解完整的结构字段集,包括由于嵌入匿名成员而可用的字段,同时排除由于与另一个字段处于同一级别而被擦除的字段同名。
这样做的逻辑并不复杂,但它有点微妙且容易出错。
此 CL
reflect.VisibleFields()向reflect包中添加了一个新函数,该函数返回适用于给定结构类型的完整有效字段集。
fields := reflect.VisibleFields(typ)
for j, field := range fields {
...
}
Run Code Online (Sandbox Code Playgroud)
例子,
type employeeDetails struct {
id int16
name string
designation string
}
func structIterator() {
fields := reflect.VisibleFields(reflect.TypeOf(struct{ employeeDetails }{}))
for _, field := range fields {
fmt.Printf("Key: %s\tType: %s\n", field.Name, field.Type)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
87089 次 |
| 最近记录: |