go的反射不同于java,可以通过TypeOf和ValueOf两种方式,且go不能通过反射修改私有变量,也不能通过反射调用私有方法。
1、TypeOf
代码:
/*
typeof返回类型,不带值
*/
type B struct {
a string //private
C int //public
}
//public
func (b *B) SetA(a string) {
b.a = a
}
//private
func (b *B) setC(c int) {
b.C = c
}
func TestB(t *testing.T) {
b := &B{
a: "libo",
C: 12,
}
typeb := reflect.TypeOf(b)
fa,_ := typeb.Elem().FieldByName("a")
fmt.Println("1:", fa)
fc, _ := typeb.Elem().FieldByName("C")
fmt.Println("2:", fc)
ma,_ := typeb.MethodByName("SetA") // 此时不能添加.Elem()
fmt.Println("3:", ma.Type)
ma.Func.Call([]reflect.Value{reflect.ValueOf(b), reflect.ValueOf("asdfg")}) // 注意方法参数
fmt.Println("4:", b.a)
}
结果:
2、ValueOf
代码:
/*
ValueOf包含字段类型和值的所有信息,且利用反射调用对象方法时参数不同
*/
func TestA(t *testing.T) {
b := &B{
a: "libo",
C: 12,
}
value := reflect.ValueOf(b)
fa := value.Elem().FieldByName("a") // 私有成员变量不能修改
fmt.Println("1: ",fa)
fc := value.Elem().FieldByName("C")
fc.SetInt(32) // 修改值
fmt.Println("2: ",fc.Int())
ma := value.MethodByName("SetA")
fmt.Println("3: ",ma.Type())
ma.Call([]reflect.Value{reflect.ValueOf("asdfg")}) // 注意参数
fmt.Println("4: ",fa.String())
fmt.Println("5: ",b.a)
}
结果:
有疑问加站长微信联系(非本文作者)