01、反射字段和方法
1 package main 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 type Name struct { 9 name string 10 age int 11 } 12 13 func (n Name) Print() { 14 fmt.Println(n.name) 15 } 16 17 func main() { 18 n1 := Name{"abc", 10} 19 Info(n1) 20 } 21 22 func Info(a interface{}) { 23 t := reflect.TypeOf(a) 24 v := reflect.ValueOf(a) 25 26 fmt.Println("Type name:", t.Name()) 27 28 //不是struct类型时,获取不到Field信息 29 if k := t.Kind(); k != reflect.Struct { 30 fmt.Println("传入的类型不是struct类型") 31 return 32 } 33 34 fmt.Println("字段") 35 for i := 0; i < t.NumField(); i++ { 36 f := t.Field(i) 37 val := v.Field(i) 38 fmt.Printf("%6s %v=%v\n", f.Name, f.Type, val) 39 } 40 fmt.Println("方法", t.NumMethod()) 41 for i := 0; i< t.NumMethod(); i ++ { 42 m := t.Method(i) 43 fmt.Printf("%6s %v\n", m.Name, m.Type) 44 } 45 }
02、反射匿名字段
1 package main 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 type Name struct { 9 name string 10 age int 11 } 12 13 type Person struct { 14 Name 15 job string 16 } 17 18 func main() { 19 p := Person{ 20 Name: Name{"hello", 10}, 21 job: "software engineer", 22 } 23 t := reflect.TypeOf(p) 24 fmt.Printf("%#v\n", t.FieldByIndex([]int{0,1})) 25 }
reflect.StructField{Name:"age", PkgPath:"main", Type:(*reflect.rtype)(0x4cda00), Tag:"", Offset:0x10, Index:[]int{1}, Anonymous:false}
03、反射修改值
1 package main 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 type Name struct { 9 Name string 10 age int 11 } 12 13 func main() { 14 n := Name{"aaa", 10} 15 v := reflect.ValueOf(&n) 16 if v.Kind() != reflect.Ptr { 17 fmt.Println("不可修改") 18 return 19 } else { 20 v = v.Elem() 21 } 22 f := v.FieldByName("Name") 23 if !f.IsValid() { 24 fmt.Println("未找到字段") 25 return 26 } 27 if !f.CanSet() { 28 fmt.Println("找到的字段不可修改") 29 return 30 } 31 if f.Kind() == reflect.String { 32 f.SetString("abc") 33 } 34 fmt.Println(n) 35 }
04、反射调用方法
1 package main 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 type Name struct { 9 Name string 10 age int 11 } 12 13 func(n *Name) SetName(name string) { 14 n.Name = name 15 } 16 17 func main() { 18 n := Name{"aaa", 10} 19 v := reflect.ValueOf(&n) 20 vm := v.MethodByName("SetName") 21 if !vm.IsValid() { 22 fmt.Println("获取的方法不合法") 23 return 24 } 25 vm.Call([]reflect.Value {reflect.ValueOf("abc")}) 26 fmt.Printf("%v", n) 27 }