Go语言的反射

Home

代码例子

反射使用TypeOf和ValueOf函数从接口中获取目标对象信息
package main
import(
    "fmt"
    "reflect"
)
type User struct{
    name    string
    age     string
}
func (u User)Hello(){
    fmt.Println("Hello Reflection")
}
func main(){
    u := User{"zuo",22}
    info(u)
}
func Info(o interface{}){
    t := reflect.TypeOf(o)//获取接口的类型
    fmt.Println("Type":t.Name())//Type:User
    
    //处理传进来是指针的情况
    if k := t.Kind();k!=reflect.Struct{
        fmt.Println("传进来的接口为指针,不能继续")
        return
    }
    
    
    v := reflect.ValueOf(o)//获取值
    //获取接口的字段以及字段对应的值
    for i := 0;i<t.NumField();i++{
        f = t.Field(i)//通过索引获取对应的字段
        val := v.Field(i).Interface()//通过索引获取对应字段的值
        fmt.Printf("%6s:%v = %v\n",f.Name,t.Type,val)
        /**
        name :string = "zuo"
        age  :int = 22
        */
        
    }
    //获取接口对应的方法信息
    for i := 0;i<t.NumMethod();i++{
        m := t.Method(i)
        fmt.Printf("%6s:%v\n",m.Name,m.Type)//Hello:func(main.User)
    }
    
}
反射会将匿名字段作为独立字段

import(
	"fmt"
	"reflect"
)
type User struct{
	name    string
	age     int
}
type Manager struct {
	User    //  匿名字段
	title string
}
func main(){
	m := Manager{User:User{"zuo",22},title:"主题"}
	t :=reflect.TypeOf(m)

	fmt.Printf("%#v\n",t.Field(0))
	//输出:reflect.StructField{Name:"User", PkgPath:"", Type:(*reflect.rtype)(0x10aeda0), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:true}
	
	fmt.Printf("%#v\n",t.Field(1))
	//输出:reflect.StructField{Name:"title", PkgPath:"main", Type:(*reflect.rtype)(0x10a2ea0), Tag:"", Offset:0x18, Index:[]int{1}, Anonymous:false}
	
	fmt.Printf("%#v\n",t.FieldByIndex([]int{0,0}
	))
	//根据索引取值
	//输出:reflect.StructField{Name:"name", PkgPath:"main", Type:(*reflect.rtype)(0x10a2f80), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:false}

}
想要利用反射修改对象状态
待补充