2、反射是如何 获取 匿名字段呢?
//反射 是如何处理 匿名字段的?
package main
import (
"reflect"
"fmt"
)
type Stu struct {
Id int
Name string
Age int
}
type Man struct {
//这里你要注意一下,你创建的属性,是有顺序的,是有下标的
//如Stu 下标 就是0, title下标就是1
// Stu 就是匿名属性
Stu
title string
}
func main() {
//注意,对匿名字段进行初始化时的方式,其实本质上跟其他属性是一样的
m := Man{Stu:Stu{Id:2,Name:"Jack",Age:19}, title:"Manager"}
t := reflect.TypeOf(m)
//取匿名字段的方式
//FieldByIndex 方法,传入的是一个切片slice类型
//第1个0,表示,匿名字段在Man中的下标位置
//第2个0,表示,你要取匿名字段中哪个属性的下标
fmt.Printf("%#v\n", t.FieldByIndex([]int{0,0})) //取的是id
fmt.Printf("%#v\n", t.FieldByIndex([]int{0,1})) //取的是Name
fmt.Printf("%#v\n", t.FieldByIndex([]int{0,2})) //取的是Age
}
3、通过反射对基本类型进行修改
//如果通过反射,对基本类型进行修改
package main
import (
"reflect"
"fmt"
)
func main() {
//下面测试,对基本类型的修改 操作
x := 456
//传递的参数是 地址
v := reflect.ValueOf(&x)
//Elem方法,是取出元素值来,然后通过setint方法,进行重新设置
v.Elem().SetInt(789)
fmt.Println(x)
}
4、通过反射 对复杂类型进行修改
//如果通过反射,对复杂类型进行修改
package main
import (
"reflect"
"fmt"
)
type Teac struct {
Id int
Name string
Age int
}
func main() {
teac := Teac{Id:5,Name:"Ant-man",Age:23}
fmt.Println("teac:\t", teac)
//传递的是 地址哦
Set(&teac)
fmt.Println("teac:\t", teac)
}
func Set(o interface{}) {
v := reflect.ValueOf(o)
if v.Kind() == reflect.Ptr && !v.Elem().CanSet() {
fmt.Printf("xxx")
return
}else{
v = v.Elem()
}
// 通过FieldByName 这个方法,直接输入 名称,来获取
f := v.FieldByName("Name")
//校验,是否取到Name属性的值
if !f.IsValid() {
fmt.Printf("BAD")
return
}
//然后,再校验,类型是否匹配
if f.Kind() == reflect.String {
f.SetString("Iron Man")
}
}
5、通过反射对方法进行动态调用
//通过反射,进行方法的调用,相当于动态调用了
package main
import (
"fmt"
"reflect"
)
type Teacher struct {
Id int
Name string
Age int
}
//通过receiver将Show方法,跟Teacher类型,进行绑定
func (teacher Teacher)Show(name string) {
fmt.Println("hello, ", name, ", my name is ", teacher.Name)
}
//注意======目前没有发现====如何通过====反射===来获取=====私有方法
func (teacher Teacher)info(){
fmt.Println("=====")
}
func main() {
teacher := Teacher{Id:34, Name:"Thor",Age:34}
teacher.Show("Hawkeye")
//下面通过反射,调用show方法
v := reflect.ValueOf(teacher)
//获取show方法
m := v.MethodByName("Show")
//校验一下,是否获取到show方法呢
if !m.IsValid() {
fmt.Printf("=======没有获取到制定的方法====")
return
}
//参数必须是切片类型
//reflect.Value{} 这里面,可以设定多个参数类型
//目前,我们这里只有一个string类型的参数
//
args := []reflect.Value{reflect.ValueOf("Hulk")}
m.Call(args)
}
网站题目:Go语言之reflection
标题网址:http://scyanting.com/article/psepog.html