Golang基础_10-反射reflection

Posted leafs99

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang基础_10-反射reflection相关的知识,希望对你有一定的参考价值。

目录

@

反射基本操作

  • 反射可大大提高程序的灵活性,使得interface有更大的发挥余地
  • 反射使用TypeOf和ValueOf函数从 接口 中获取目标对象信息
type User struct
    Id int
    Name string
    Age int

func (u User) Hello() 
    fmt.Println("Hello World.")

func main()
    u := User1,"kk",12
    Info(u)

func Info(o interface)
    //获取类型信息
    t := reflect.TypeOf(o)
    fmt.Println("Type:",t.Name())

    //用以判断传入的类型是否是struct类型,而不是指针什么的
    if k:=t.Kind();k!=reflect.Struct 
        fmt.Println("XXXXXXXXXX")
        return
    
    
    //获取字段信息
    v := reflect.ValueOf(o)
    fmt.Println("Field:")

    for i:=0;i<t.NumField();i++ 
        f := t.Field(i)
        val :=  v.Field(i).Interface()
        fmt.Printf("%6s: %v = %v\n",f.Name,f.Type,val)

    //获取方法信息
    for i:= 0;i<t.NumMethod();i++ 
        m := t.Method(i)
        fmt.Printf("%6s: %v\n",m.Name,m.Type)
    

/*
> Output:
command-line-arguments
Type: User
Field:
    Id: int = 1
  Name: string = kk
   Age: int = 12
 Hello: func(main.User)
*/

反射匿名或嵌入字段

  • 反射会将匿名字段作为独立字段(匿名字段本质)
type User struct 
    Id int
    Name string
    Age int

//匿名字段
type Manager struct 
    User
    title string

func main()
    m := ManagerUser: User1,"hel",12, title:"123"
    t := reflect.TypeOf(m)
    //通过slice获取值
    fmt.Printf("%#v\n",t.FieldByIndex([]int0,0))

/*
> Output:
command-line-arguments
reflect.StructFieldName:"Id", PkgPath:"", Type:(*reflect.rtype)(0x49ce80), Tag:"", Offset:0x0, Index:[]int0, Anonymous:false
*/

修改目标对象

  • 想要利用反射修改对象状态,前提是interface.data是settable,即pointer-interface
type User struct 
    Id int
    Name string
    Age int

type Manager struct 
    User
    title string

func main()
    u := User1,"ok",12
    Set(&u)
    fmt.Println(u)

//通过ptr(point interface)修改字段的值
func Set(o interface) 
    v := reflect.ValueOf(o)
    if v.Kind()!=reflect.Ptr&&!v.Elem().CanSet()
        fmt.Println("XXX")
        return
    else
        v = v.Elem()
    
    f:=v.FieldByName("Name")
    if !f.IsValid()
        fmt.Println("BAD")
        return
    
    if f.Kind()==reflect.String 
        f.SetString("BYBYBY")
    

/*
> Output:
command-line-arguments
1 BYBYBY 12
*/

动态调用方法

  • 通过反射可以“动态”调用方法
type User struct 
    Id int
    Name string
    Age int

func (u User)Hello(name string) 
    fmt.Println("Hello",name,", my name is",u.Name)

func main() 
    u := User1,"OK",12
    v := reflect.ValueOf(u)
    mv := v.MethodByName("Hello")
    //args是个slice,
    //利用反射动态调用
    args := []reflect.Valuereflect.ValueOf("joe")
    mv.Call(args)

/*
> Output:
command-line-arguments
Hello joe , my name is OK
*/

以上是关于Golang基础_10-反射reflection的主要内容,如果未能解决你的问题,请参考以下文章

golang 基础——反射

golang 基础——反射

golang基础--reflect反射

Go 语言:别再问我什么是反射

阶段1 语言基础+高级_1-3-Java语言高级_09-基础加强_第2节 反射_10_反射_Class对象功能_获取Method成员方法

golang 反射