hapiman / jsrice

A common utils using in javascript
0 stars 0 forks source link

Golang反射 #40

Open hapiman opened 6 years ago

hapiman commented 6 years ago

关于Golang中方法及属性说明

package ref 

type Address struct {
    City string
    Area string
}
type Student struct {
    Address
    Name string
    Age  int
}

func (this Student) Say() {
    fmt.Println("hello, i am ", this.Name, "and i am ", this.Age)
}
func (this Student) Hello(word string) {
    fmt.Println("hello", word, ". i am ", this.Name)
}
func StructInfo(o interface{}) {
    t := reflect.TypeOf(o)  //获取对象的类型 ref.Struct 
    fmt.Println(t.Name(), "object type: ", t.Name()) // t.Name就是对象的名称 
    fmt.Println("===>", t.Kind(), reflect.Struct)
    if k := t.Kind(); k != reflect.Struct {  // t.Kind()对象类型 struct
        fmt.Println("the object is not a struct, but it is", t.Kind())
        return
    }
    v := reflect.ValueOf(o)  // 获取对象的值 {{Shanghai Pudong} chain 23}
    fmt.Println(t.Name(), "object value: ", v)
    fmt.Println(t.Name(), "fields: ", t.NumField()) //获取对象的字段  t.NumField() 字段个数
    for i := 0; i < t.NumField(); i++ {
        f := t.Field(i)  // 选择字段,包含了某个字段所有属性,包括Name, Type, val
        val := v.Field(i).Interface() // 转化获取字段值
        fmt.Printf("%6s:%v = %v \n", f.Name, f.Type, val)
        //通过递归调用获取子类型的信息
         t1 := reflect.TypeOf(val)

         if k := t1.Kind(); k == reflect.Struct {
            StructInfo(val)
        }
    }
    //获取对象的函数 t.NumMethod()获取方法的数量
    fmt.Println(t.Name(), "methods: ", t.NumMethod()) 
    for i := 0; i < t.NumMethod(); i++ {
        m := t.Method(i) // 选取方法
        fmt.Printf("%10s:%v \n", m.Name, m.Type)
    }
}

func main() {
    stu := Student{Address: Address{City: "Shanghai", Area: "Pudong"}, Name: "chain", Age: 23}
    StructInfo(stu)
}
hapiman commented 6 years ago

t := reflect.typeOf(o)获取到包名.类型名,如上:ref.Student 属性字段Fields建立在typeOf之上 t.Name()对象的名称 t.Kind()对象类型,如上为struct t.NumField()获取对象的属性值 t.Field(i)获取某个属性所有信息 A t.NumMethod()获取结构体上的方法数量 m := t.Method(i) 选择某个方法,通过m.Name, m.Type查看方法详情

v := reflect.ValueOf(o)获取到结构体的值的引用 v=v.Elem() 将指针转化的结构值,特别要注意valueOf()中的变量是否指针或是值 v.FieldByName("Name")直接获取值 val := v.Field(i).Interface() 获取某个属性的值 B fmt.Printf("%6s:%v = %v \n", f.Name, f.Type, val) 关联AB m2 := v.MethodByName("Say") 在对象的值上调用某个方法 m2.Call([]reflect.Value{reflect.ValueOf("iris")}) 调用方法,执行方法

如果想通过反射获取某个字段的值,就必须使用val := v.Field(i).Interface()获取,也就是使用reflect.valueOf(),而不使用reflect.typeOf()