Reflect-Go一分鐘快速入門

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末燃辖,一起剝皮案震驚了整個濱河市鬼店,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黔龟,老刑警劉巖妇智,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滥玷,死亡現(xiàn)場離奇詭異,居然都是意外死亡巍棱,警方通過查閱死者的電腦和手機(jī)惑畴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拉盾,“玉大人桨菜,你說我怎么就攤上這事∽狡” “怎么了倒得?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長夭禽。 經(jīng)常有香客問我霞掺,道長,這世上最難降的妖魔是什么讹躯? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任菩彬,我火速辦了婚禮,結(jié)果婚禮上潮梯,老公的妹妹穿的比我還像新娘骗灶。我一直安慰自己,他們只是感情好秉馏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布耙旦。 她就那樣靜靜地躺著,像睡著了一般萝究。 火紅的嫁衣襯著肌膚如雪免都。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天帆竹,我揣著相機(jī)與錄音绕娘,去河邊找鬼。 笑死栽连,一個胖子當(dāng)著我的面吹牛险领,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秒紧,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼舷暮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了噩茄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤复颈,失蹤者是張志新(化名)和其女友劉穎绩聘,沒想到半個月后沥割,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凿菩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年机杜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片衅谷。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡椒拗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出获黔,到底是詐尸還是另有隱情蚀苛,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布玷氏,位于F島的核電站堵未,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏盏触。R本人自食惡果不足惜渗蟹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赞辩。 院中可真熱鬧雌芽,春花似錦、人聲如沸辨嗽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽召庞。三九已至岛心,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間篮灼,已是汗流浹背忘古。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诅诱,地道東北人髓堪。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像娘荡,于是被迫代替她去往敵國和親干旁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容