在Golang项目开发中我们常会使用到空接口interface{}与reflect。下面是作者在学习Golang过程中遇到的一些关于Reflect的用法,即使总结并记录。
将interface{T} 转为 interface{*T}:
我们在使用interface{}传递函参时,可能会碰到需要将传递的值类型T转变为指针类型*T,从而使他能够被赋值,可取址。思路: 根据T.type New()一个新的指针Type,并对其赋值。
func ifaceValue2Pointer(v interface{}) interface{}{
pv:=reflect.New(reflect.TypeOf(v))
pv.Elem().Set(reflect.ValueOf(v))
return pv.interface()
//fmt.Println(reflect.ValueOf(pv).Elem().CanAddr()) ----> true
}
将interface{T} 中T转为 []byte 字节流形式:
使用场景:例如使用socket建立长连接时,需要传输struct类型。思路:存储struct的指针地址,Len与Cap,通过unsafe包进行转换。
type SliceMock struct{
addr uintptr
len int
cap int
}
func struct2byte(t interface{}) []byte { //在此假设t的实例为值类型
var ts = &t
Len := unsafe.Sizeof(*ts)
p := reflect.New(reflect.TypeOf(t))
p.Elem().Set(reflect.ValueOf(t))
addr := p.Elem().UnsafeAddr() //取址
tb := &SliceMock{
addr: addr,
cap: int(Len),
len: int(Len),
}
return *(*[]byte)(unsafe.Pointer(tb))
}
//...........
func main() {
data := struct2byte(TestStruct{3,100})
var ptestStruct *TestStruct = *(**TestStruct)(unsafe.Pointer(&data))
}