if kind := t.Kind(); kind != reflect.Struct { log.Fatalf("This program expects to work on a struct; we got a %v instead.", kind) }
for i := 0; i < t.NumField(); i++ { f := t.Field(i) log.Printf("Field %03d: %-10.10s %v", i, f.Name, f.Type.Kind()) } }
该程序的目的是打印 Gift 结构中的字段。当把 g 值传递给 reflect.TypeOf() 时,g 被赋给一个 interface,此时编译器会使用类型和方法集信息来填充它。这使得我们可以遍历该 interface 结构的类型部分的 []fields 字段,得到以下输出:
1 2 3 4
2018/12/1612:00:00 Field 000: Sender string 2018/12/1612:00:00 Field 001: Recipient string 2018/12/1612:00:00 Field 002: Number uint 2018/12/1612:00:00 Field 003: Contents string
type Child struct { Name string Grade int Nice bool }
type Adult struct { Name string Occupation string Nice bool }
// search a slice of structs for Name field that is "Hank" and set its Nice // field to true. funcnice(i interface{}) { // retrieve the underlying value of i. we know that i is an // interface. v := reflect.ValueOf(i)
// we're only interested in slices to let's check what kind of value v is. if // it isn't a slice, return immediately. if v.Kind() != reflect.Slice { return }
// v is a slice. now let's ensure that it is a slice of structs. if not, // return immediately. if e := v.Type().Elem(); e.Kind() != reflect.Struct { return }
// determine if our struct has a Name field of type string and a Nice field // of type bool st := v.Type().Elem()
if nameField, found := st.FieldByName("Name"); found == false || nameField.Type.Kind() != reflect.String { return }
if niceField, found := st.FieldByName("Nice"); found == false || niceField.Type.Kind() != reflect.Bool { return }
// Set any Nice fields to true where the Name is "Hank" for i := 0; i < v.Len(); i++ { e := v.Index(i) name := e.FieldByName("Name") nice := e.FieldByName("Nice")
if name.String() == "Hank" { nice.SetBool(true) } } }