Golang的学习笔记(14)--Go反射reflect

目录

Go中的反射reflect

reflectimport reflectreflect.Typereflect.Value
func TypeOf(i interface{}) Type
func ValueOf(i interface{}) Value
ValueValue.Type()TypeTypereflect.Valuereflect.TypeKind()reflect.Kindreflect.TypeKindTypetype zhengxing intvar i zhengxingTypezhengxingKindint

反射操作解析对象实例

    下面列举一些通过反射操作来解析一些对象变量的实例:

  • 简单数据类型
import (
   "fmt"
   "reflect"
)
func main(){
   var i int = 1
   v := reflect.ValueOf(i)               //获取Value
   fmt.Println(v.Int())                     
   t := reflect.TypeOf(i)                //获取Type
   fmt.Println(t.Name()) 
}
intv.Int()intvValueValue.Float()Value.Bool()panict.Name()
  • 结构体类型
import (
   "fmt"
   "reflect"
)
type dog struct {
   name string
   age  int
}
func (d dog) Run(speed string) {
   fmt.Println(d.name, "is running", speed)
}
func main(){
   d := dog{ "dog", 2}
   t := reflect.TypeOf(d)
   fmt.Println("type: ", t.Name())
   v := reflect.ValueOf(d)
   fmt.Println("Fields:")
   for i := 0; i < t.NumField(); i++ {
      f := t.Field(i)
      val := v.Field(i)
      fmt.Println(f.Name, f.Type, val)
   }
   for i := 0; i < t.NumMethod(); i++ {
      m := t.Method(i)
      fmt.Println(m.Name, m.Type)
   }
}
t := reflect.TypeOf(d)structv := reflect.ValueOf(d)t.NumField()f := t.Field(i)val := v.Field(i)t.NumMethod()tt.Method(i)
  • 嵌套结构体
type User struct {
   Id   int
   Name string
}
type Manager struct {
   User
   title string
}
func main(){
   m := Manager{
     User:  User{1, "user"},
     title: "kk",
   }
   t := reflect.TypeOf(m)
   fmt.Println(t.Field(0))  //{User  main.User  0 [0] true}
   fmt.Println(t.Feile(1))  //{title main string  24 [1] false}               
   fmt.Println(t.FieldByIndex([]int{0, 0}))  //{Id  int  0 [0] false}
   fmt.Println(t.FieldByIndex([]int{0, 1}))  //{Name  string  8 [1] false}
}
t.Field(0)t.Field(1)UsertitleUsertruefalseManagerUsert.FieldByIndex()intsliceManagerUser

通过反射来修改对象的值

  • 简单数据类型
import "reflect"
func main(){
   x := 123
   v := reflect.ValueOf(x)
   v.Elem().SetInt(999)
}
v.Elem()vSetInt()
  • 结构体类型
type User struct {
   Id   int
   Name string
}
func main(){
   u := User{
     Id:   1,
     Name: "32",
   }
   Set(&u)
   fmt.Println(u)
}
func Set(o interface{}) {
   v := reflect.ValueOf(o)
   if v.Kind() != reflect.Ptr{
      fmt.Println("can not be set")
      return
   }
   value := v.Elem()    
   if !value.CanSet(){
      fmt.Println("can not be set")
   }
   f := value.FieldByName("Name")
   if !f.IsValid() {
      fmt.Println("can not be set")
      return
   }
  if f.Kind() == reflect.String {
      f.SetString("wangwang")
  }
}
Set
panic: reflect: reflect.flag.mustBeAssignable using value obtained using unexported field

使用反射机制动态调用方法

    使用反射机制可以在程序中动态调用方法

type dog struct {
   Name string
   Age  int
}
func (d dog) Run(speed string) {
   fmt.Println(d.name, "is running", speed)
}
func main(){
   d := dog{"gogo", 1}
   v := reflect.ValueOf(d)
   mv := v.MethodByName("Run")
   args := []reflect.Value{reflect.ValueOf("fastly")}
   mv.Call(args)
}
MethodByName()Call()reflect.Valuereflect.ValueOf()relfect.Value