Go反射深入了解
为什么会有反射
golang中的所有类型都实现了interface{}的接口,所以用interface{}定义的变量能接收任意类型的数据(包括函数类型),会自动转化为interface{}类型,当想在运行时动态的获取一个变量的类型,属性及方法时就需要使用反射。
反射中的重要接口与结构
golang中reflect包
package reflect
反射获得对象的属性
type person struct{
name string
age int
}
func main(){
per := person{name: "张三",age: 18}
valPer := reflect.ValueOf(per)
fmt.Println(valPer.Field(0).String())
fmt.Println(valPer.Field(1).Int())
//张三
//18
}
只有对象变量是struct类型的才能用反射来获取变量对应的属性
reflect.ValueOf(per) | 获得per的值 |
---|---|
.Field(index).String() | 通过索引返回对应结构体字段的信息,只能用在结构体 |
但是如果是使用的结构体指针则需要使用反射来获取指针指向的元素,通过元素去访问变量对应的属性
per := &person{name:"李四",age: 19}
valPer := reflect.ValueOf(per)
fmt.Println(valPer.Elem().Field(0).String())
fmt.Println(valPer.Elem().Field(1).Int())
//李四
//19
.Elem() | 获得结构体指针指向的元素值,必须用在ptr或interface |
---|
反射获得对象的方法
type person struct{
name string
age int
}
func (p person)print(str interface{}){
fmt.Println(str)
}
func main(){
ref := &person{name:"王二",age:20}
iref := reflect.ValueOf(ref)
fn := iref.MethodByName("print")
var str = "hello,world"
var in []reflect.Value
in = append(in,reflect.ValueOf(str))
fn.Call(in)
//hello,world
}
当想获取一个变量的自定义方法时,这个被反射的变量一定要有自己的方法
| **func (v Value)
MethodByName(name string) Value** | 返回v的名为name的方法的函数形式的Value ( 此返回值只能调用Call方法 ) | |
---|---|---|
func (v Value) Call(in []Value) []Value | 使用输入的参数in调用v所包含的方法 in必须是一个[]reflect.Value |