本文側重講解reflect反射的實踐應用,適合新手初窺門徑。html
func TypeOf(i interface{}) Type func ValueOf(i interface{}) Value 複製代碼
經過reflect.Type和reflect.Value支持的方法,能夠對輸入的動態數據進行解析。 那麼瞭解reflect.Type和reflect.Value提供的方法尤其重要,由於比較多,此介紹放在文末。golang
在reflect.Type和reflect.Value上調用Kind()方法,能夠獲得reflect.Kind類型值,從而知道動態數據的類型。這個是動態解析的鑰匙,經過反射後拿到具體的類型才能作相應的工做,逐層解析。bash
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
)
複製代碼
下述demo中默認函數
rt = reflect.TypeOf(data)
rv = reflect.ValueOf(data)
複製代碼
//遍歷結構體的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的key和value
for _, key := range rv.MapKeys() {
//其中key爲鍵的Value
rv.MapIndex(key) //鍵值的Value
}
rv.Len() //map的大小
rv.SetMapIndex() //map索引賦值
複製代碼
//遍歷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
複製代碼
if !rv.IsNil() {
rv.Elem() //指針或者interface實際指向元素
}
複製代碼
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()
複製代碼
動態解析的時候,用得比較少,這裏就不說了ui
Method | Type返回類型 | Value返回類型 | 備註 |
---|---|---|---|
Kind | Kind | Kind | 返回指定對象的Kind類型 |
NumMethod | int | int | 返回struct擁有的方法總數,包括unexported方法 |
MethodByName | Method | Value | 根據方法名找方法 |
Method | Method | Value | 返回第i個方法 |
NumField | int | int | 返回struct所包含的field數量 |
Field | StructField | Value | 取struct結構的第n個field |
FieldByIndex | StructField | Value | 嵌套的方式取struct的field,好比v.FieldByIndex([]int{1,2})等價於 v.field(1).field(2) |
FieldByName | StructFiel,bool | Value | 返回名稱匹配match函數的field |
FieldByNameFunc | StructField,bool | Value | 返回名稱匹配match函數的field |
Method | 備註 |
---|---|
Align | 分配內存時的內存對齊字節數 |
FieldAlign | 做爲struct的field時內存對齊字節數 |
Name | type名 string類型 |
PkgPath | 包路徑, "encoding/base64", 內置類型返回empty string |
Size | 該類型變量佔用字節數 |
String | type的string表示方式 |
Implements | 判斷該類型是否實現了某個接口 |
AssignableTo | 判斷該類型可否賦值給某個類型 |
ConvertibleTo | 判斷該類型可否轉換爲另一種類型 |
Comparable | 判斷該類型變量是否能夠比較 |
ChanDir | 返回channel的方向 recv/send/double |
IsVariadic | 判斷函數是否接受可變參數 |
Elem | 取該類型的元素 |
In | 函數第n個入參 |
Out | 函數第n個出參 |
NumIn | 函數的入參數個數 |
NumOut | 函數的出參個數 |
Key | 返回map結構的key類型Type |
Len | 返回array的長度 |
Method | 備註 |
---|---|
Addr | v的指針,前提時CanAddr()返回true |
Bool | 取值,布爾類型 |
Bytes | 取值,字節流 |
Call | 調用函數 |
CallSlice | 調用具備可變參的函數 |
CanAddr | 判斷可否取址 |
CanInterface | 判斷Interface方法可否使用 |
CanSet | 判斷v的值可否改變 |
Cap | 判斷容量 Array/Chan/Slice |
Close | 關閉Chan |
Complex | 取值,複數 |
Convert | 返回將v轉換位type t的結果 |
Elem | 返回interface包含或者Ptr指針的實際值 |
Float | 取值,浮點型 |
Index 索引操做 | Array/Slice/String |
Int | 取值,整型 |
Interface | 將當前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發送 |
Set | 將x賦值給v,類型要匹配 |
SetBool | Bool賦值,須要先判斷CanSet()爲true |
SetBytes | Bytes賦值 |
SetCap | slice調整切片容量 |
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非阻塞發送 |
Type | 返回value的Type |
UnsafeAddr | 返回指向value的data的指針 |
Type和Value方法: www.cnblogs.com/ksir16/p/90…spa