Reflect-Go: 一分鐘快速入門
本文側重講解 reflect 反射的實踐應用,適合新手初窺門徑。
reflect 兩個基本功能
func TypeOf(i interface{}) Type
func ValueOf(i interface{}) Value
通過 reflect.Type 和 reflect.Value 支持的方法,可以對輸入的動態數據進行解析。那麼瞭解 reflect.Type 和 reflect.Value 提供的方法尤爲重要,因爲比較多,此介紹放在文末。
reflect.Kind
在 reflect.Type 和 reflect.Value 上調用 Kind() 方法,可以得到 reflect.Kind 類型值,從而知道動態數據的類型。這個是動態解析的鑰匙,通過反射後拿到具體的類型才能做相應的工作,逐層解析。
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 通過調用 Elem() 方法得到指向元素的值,再進入循環解析。
-
Slice、Array、Map、Struct 複合數據類型,通過各自的方法拿到他們組成類型值,再進入循環解析
-
直到爲基礎數據類型或者 Func、Chan、UnsafePointer。
reflect 解析動態數據流程
具體類型解析
下述 demo 中默認
rt = reflect.TypeOf(data)
rv = reflect.ValueOf(data)
Struct
//遍歷結構體的Field
for i := 0; i < rt.NumField(); i++ {
rt.Field(i) //第i個Field的StructField
rv.Filed(i) //第i個Field的Value
}
//遍歷結構體的方法
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) //調整切片容量
rv.Slice(i, j) //返回切片s[i:j]的Value
Ptr Interface
if !rv.IsNil() {
rv.Elem() //指針或者interface實際指向元素
}
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結構中的值,必須類型一致
rv.Set()
rv.SetBool()
rv.SetInt()
rv.SetUint()
rv.SetFloat()
rv.SetComplex()
rv.SetString()
rv.SetBytes()
Func Chan UnsafePointer
動態解析的時候,用得比較少,這裏就不說了
Type 和 Value 方法
Type 和 Value 擁有的同名方法
Type 獨有的方法
Value 獨有的方法
引用鏈接
Type 和 Value 方法: https://www.cnblogs.com/ksir16/p/9040656.html
轉自:
segmentfault.com/a/1190000021549498
Go 開發大全
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/f9iTTtf2r0U5sACAheIydA