Reflect
本文側(cè)重講解reflect反射的實(shí)踐應(yīng)用牢硅,適合新手初窺門徑蹬耘。
reflect兩個基本功能
- reflect.TypeOf() 動態(tài)獲取輸入數(shù)據(jù)的類型
- reflect.ValueOf() 動態(tài)獲取輸入數(shù)據(jù)的值
func TypeOf(i interface{}) Type
func ValueOf(i interface{}) Value
通過reflect.Type和reflect.Value支持的方法,可以對輸入的動態(tài)數(shù)據(jù)進(jìn)行解析减余。
那么了解reflect.Type和reflect.Value提供的方法尤為重要综苔,因?yàn)楸容^多,此介紹放在文末。
reflect.Kind
在reflect.Type和reflect.Value上調(diào)用Kind()方法如筛,可以得到reflect.Kind類型值堡牡,從而知道動態(tài)數(shù)據(jù)的類型。這個是動態(tài)解析的鑰匙杨刨,通過反射后拿到具體的類型才能做相應(yīng)的工作晤柄,逐層解析。
const (
Invalid Kind = iota
Bool
Int
Int8
Int16
Int32
Int64
Uint
Uint8
Uint16
Uint32
Uint64
Uintptr
Float32
Float64
Complex64
Complex128
Array
Chan
Func
Interface
Map
Ptr
Slice
String
Struct
UnsafePointer
)
解析流程
- Ptr指針和Interface 通過調(diào)用Elem()方法得到指向元素的值妖胀,再進(jìn)入循環(huán)解析芥颈。
- Slice、Array赚抡、Map爬坑、Struct復(fù)合數(shù)據(jù)類型,通過各自的方法拿到他們組成類型值涂臣,再進(jìn)入循環(huán)解析
-
直到為基礎(chǔ)數(shù)據(jù)類型或者Func盾计、Chan、UnsafePointer肉康。
reflect解析動態(tài)數(shù)據(jù)流程
具體類型解析
下述demo中默認(rèn)
rt = reflect.TypeOf(data)
rv = reflect.ValueOf(data)
Struct
//遍歷結(jié)構(gòu)體的Field
for i := 0; i < rt.NumField(); i++ {
rt.Field(i) //第i個Field的StructField
rv.Filed(i) //第i個Field的Value
}
//遍歷結(jié)構(gòu)體的方法
for i := 0; i < rt.NumMethod(); i++ {
rt.Method(i) //第i個方法的Method
rv.Method(i) //第i個方法的Value
}
Map
//遍歷Map的key和value
for _, key := range rv.MapKeys() {
//其中key為鍵的Value
rv.MapIndex(key) //鍵值的Value
}
rv.Len() //map的大小
rv.SetMapIndex() //map索引賦值
Slice Array
//遍歷Slice或者Array
for i := 0; i < rv.Len(); i++ {
rv.Index(i) //子元素的Value
}
rv.Cap() //獲取切片或者Array容量
rv.SetCap(i) //調(diào)整切片容量
rv.Slice(i, j) //返回切片s[i:j]的Value
Ptr Interface
if !rv.IsNil() {
rv.Elem() //指針或者interface實(shí)際指向元素
}
Bool Int Unit Float Complex String
rv.Bool() //返回bool
rv.Int() //返回int64
rv.Uint() //返回uint64
rv.Float() //返回float64
rv.Complex() //返回complex128
rv.Sting() //返回string
//修改Value結(jié)構(gòu)中的值闯估,必須類型一致
rv.Set()
rv.SetBool()
rv.SetInt()
rv.SetUint()
rv.SetFloat()
rv.SetComplex()
rv.SetString()
rv.SetBytes()
Func Chan UnsafePointer
動態(tài)解析的時候,用得比較少吼和,這里就不說了
Type和Value方法
Type和Value擁有的同名方法
Method | Type返回類型 | Value返回類型 | 備注 |
---|---|---|---|
Kind | Kind | Kind | 返回指定對象的Kind類型 |
NumMethod | int | int | 返回struct擁有的方法總數(shù)涨薪,包括unexported方法 |
MethodByName | Method | Value | 根據(jù)方法名找方法 |
Method | Method | Value | 返回第i個方法 |
NumField | int | int | 返回struct所包含的field數(shù)量 |
Field | StructField | Value | 取struct結(jié)構(gòu)的第n個field |
FieldByIndex | StructField | Value | 嵌套的方式取struct的field,比如v.FieldByIndex([]int{1,2})等價于 v.field(1).field(2) |
FieldByName | StructFiel,bool | Value | 返回名稱匹配match函數(shù)的field |
FieldByNameFunc | StructField,bool | Value | 返回名稱匹配match函數(shù)的field |
Type獨(dú)有的方法
Method | 備注 |
---|---|
Align | 分配內(nèi)存時的內(nèi)存對齊字節(jié)數(shù) |
FieldAlign | 作為struct的field時內(nèi)存對齊字節(jié)數(shù) |
Name | type名 string類型 |
PkgPath | 包路徑炫乓, "encoding/base64"刚夺, 內(nèi)置類型返回empty string |
Size | 該類型變量占用字節(jié)數(shù) |
String | type的string表示方式 |
Implements | 判斷該類型是否實(shí)現(xiàn)了某個接口 |
AssignableTo | 判斷該類型能否賦值給某個類型 |
ConvertibleTo | 判斷該類型能否轉(zhuǎn)換為另外一種類型 |
Comparable | 判斷該類型變量是否可以比較 |
ChanDir | 返回channel的方向 recv/send/double |
IsVariadic | 判斷函數(shù)是否接受可變參數(shù) |
Elem | 取該類型的元素 |
In | 函數(shù)第n個入?yún)?/td> |
Out | 函數(shù)第n個出參 |
NumIn | 函數(shù)的入?yún)?shù)個數(shù) |
NumOut | 函數(shù)的出參個數(shù) |
Key | 返回map結(jié)構(gòu)的key類型Type |
Len | 返回array的長度 |
Value獨(dú)有的方法
Method | 備注 |
---|---|
Addr | v的指針,前提時CanAddr()返回true |
Bool | 取值末捣,布爾類型 |
Bytes | 取值侠姑,字節(jié)流 |
Call | 調(diào)用函數(shù) |
CallSlice | 調(diào)用具有可變參的函數(shù) |
CanAddr | 判斷能否取址 |
CanInterface | 判斷Interface方法能否使用 |
CanSet | 判斷v的值能否改變 |
Cap | 判斷容量 Array/Chan/Slice |
Close | 關(guān)閉Chan |
Complex | 取值,復(fù)數(shù) |
Convert | 返回將v轉(zhuǎn)換位type t的結(jié)果 |
Elem | 返回interface包含或者Ptr指針的實(shí)際值 |
Float | 取值箩做,浮點(diǎn)型 |
Index 索引操作 | Array/Slice/String |
Int | 取值莽红,整型 |
Interface | 將當(dāng)前value以interface{}形式返回 |
IsNil | 判斷是否為nil,chan, func, interface, map, pointer, or slice value |
IsValid | 是否是可操作的Value邦邦,返回false表示為zero Value |
Len | 適用于Array, Chan, Map, Slice, or String |
MapIndex | 對map類型按key取值 |
MapKeys | map類型的所有key的列表 |
OverflowComplex | 溢出判斷 |
OverflowFloat | 溢出判斷 |
OverflowInt | 溢出判斷 |
OverflowUint | 溢出判斷 |
Pointer | 返回uintptr 適用于slice |
Recv | chan接收 |
Send | chan發(fā)送 |
Set | 將x賦值給v安吁,類型要匹配 |
SetBool | Bool賦值,需要先判斷CanSet()為true |
SetBytes | Bytes賦值 |
SetCap | slice調(diào)整切片容量 |
SetMapIndex | map索引賦值 |
SetUint | Unit賦值 |
SetPointer | unsafe.Pointer賦值 |
SetString | String賦值 |
Slice | return v[i:j] 適用于Array/Slict/String |
String | return value的string表示方法 |
TryRecv | chan非阻塞接收 |
TrySend | chan非阻塞發(fā)送 |
Type | 返回value的Type |
UnsafeAddr | 返回指向value的data的指針 |
引用鏈接
Type和Value方法: https://www.cnblogs.com/ksir16/p/9040656.html