Golang-100-Days/Day16-20(Go语言基础进阶)/day19_Go语言反射.md at master · rubyhan1314/Golang-100-Days (github.com)
7-19 接口:底层实现_哔哩哔哩_bilibili
一、interface接口
接口类型内部存储了一对pair(value,Type)
type interface {
type *Type // 类型信息
data unsafe.Pointer // 指向具体数据
}
空接口类型
非空接口类型
接口类型对象接收实际对象:
1)创建Reader接口类型对象 r:
io包下的Reader接口类型
2) 创建指针File类型对象 file :
File指针类型实现了Read()和Write()方法:
3) 将实现类对象 r 赋值给 接口类型Reader对象 r
这里体现多态。
4)创建Writer接口类型对象 w
将Reader接口类型r对象强转为 Writer接口类型对象,
这里可以实现强转是因为接口类型强转看的是内部存储的type属性:
实质上是因为r对象pair的type为*File,而*File类型又实现了Write()方法,
也就是实现了Writer接口。强转的过程可以看作是Writer接口类型对象w接收实现类型为*File对象的过程。
二、 reflect
1) 通过反射获取接口类型对象的具体数据和类型
reflect.TypeOf()获取 pair中的type
reflect.ValueOf()获取 pair中的data
reflect.TypeOf()
返回值类型为Type,表示a对象通过反射获取的typeOf对象存储了int类型的的相关信息。
reflect.ValueOf()
返回值类型为Value,Value类型中存储了值的相关信息,包括了值的类型,值的具体数据。
reflect.ValueOf().Kind()
返回值类型为Kind
reflect包下的常量类型Kind
也就是uint类型
2) 通过反射获取设置对象属性及调用对象方法。
2.1) 创建对象Person,设置属性和方法
2.2)反射属性和方法
personObj := Person{Name: "银灰", Age: 18}
创建对象
reflect.ValueOf(&personObj)
获取Value对象时使用指针,让Value中存储的是personObj对象属性的地址,才能修改personObj对象属性;
否则默认会深拷贝一个对象,修改属性跟原对象不相干。
valueObj.FieldByName("Name").SetString("银灰前夫哥")
设置属性
typeObj.Field(i)
获取属性名
valueObj.Field(i)获取属性 的对应值
valueMsg := reflect.ValueOf(personObj)获取Value对象
valueMsg.MethodByName("GetAll").Call([]reflect.Value{})
调用对象方法
valueMsg.MethodByName("GetAll2").Call([]reflect.Value{reflect.ValueOf("萨卡兹沦陷"), reflect.ValueOf(2)})
调用对象方法
2.3)Kind()和 TypeOf()
同样都是获取类型,Kind()获取go包中已存在的类型,对于自定义的结构体类型只会显示struct.
显示具体类型使用reflect.TypeOf()