Go語言反射
Go語言反射
①反射可以在運行時動態(tài)獲取變量的各種信息,比如變量的類型(type),類別(kind)。
②如果是結(jié)構(gòu)體變量,還可以獲取到結(jié)構(gòu)體本身的信息(包括結(jié)構(gòu)體的字段、方法)。
③通過反射,可以修改變量的值,可以調(diào)用關(guān)聯(lián)的方法。
④使用反射,需要 import (“reflect”)
?
反射應(yīng)用場景:
①不知道接口調(diào)用哪個函數(shù),根據(jù)傳入?yún)?shù)在運行時確定調(diào)用的具體接口,這種需要對函數(shù)或方法反射。例如以下這種橋接模式。
func bridge(funcPtr interface,?args ...interface0{})
第一個參數(shù)funcPtr以接口的形式傳入函數(shù)指針,函數(shù)參數(shù)args以可變參數(shù)的形式傳入,bridge函數(shù)中可以用反射來動態(tài)執(zhí)行funcPtr函數(shù)。
?
②對結(jié)構(gòu)體序列化時,如果結(jié)構(gòu)體有指定Tag,也會使用到反射生成對應(yīng)的字符串。
?
反射重要的函數(shù)和概念:
①reflect.TypeOf(變量名),獲取變量的類型,返回reflect.Type類型
②reflect.ValueOf(變量名),獲取變量的值,返回reflect.Value類型reflect.Value是一個
結(jié)構(gòu)體類型。通過reflect.Value,可以獲取到關(guān)于該變量的很多信息。
③變量、interface{}?和 reflect.Value是可以相互轉(zhuǎn)換的,這點在實際開發(fā)中,會經(jīng)常使用到。


快速入門:
①演示對(基本數(shù)據(jù)類型、interface{}、reflect.Value)進行反射的基本操作。

?②演示對(結(jié)構(gòu)體類型、interface{}、reflect.Value)進行反射的基本操作。

?
反射的注意事項和細節(jié):
①reflect.Value.Kind,返回的是一個常量,Kind代表Type類型值的具體分類,零值表示非法分類。
②Type和Kind 的區(qū)別:
Type是類型,Kind 是類別,Type和Kind可能是相同的,也可能是不同的。
比如:var num int = 10;num 的Type和Kind都是int。
比如:var stu Student;stu的Type是 pkg1.Student,Kind是struct。
?
④使用反射的方式來獲取變量的值(并返回對應(yīng)的類型),要求數(shù)據(jù)類型匹配,比如x是int,那么就應(yīng)該使用reflect.Value(x).Int(),而不能使用其它的,否則報panic。
?
⑤通過反射的來修改變量,注意當使用SetXxx方法來設(shè)置,需要通過對應(yīng)的指針類型來完成,這樣才能改變傳入的變量的值,同時需要使用到reflect.Value.Elem()方法。

⑥r(nóng)eflect.Value.Elem()

反射課堂練習:
①給你一個變量var v float64= 1.2,請使用反射來得到它的reflect.Value,然后獲取對應(yīng)的Type,Kind和值,并將reflect.Value轉(zhuǎn)換成interface{},再將interface{}轉(zhuǎn)換成float64。

反射最佳實踐:
①使用反射來遍歷結(jié)構(gòu)體的字段,調(diào)用結(jié)構(gòu)體的方法,并獲取結(jié)構(gòu)體標簽的值。



②使用反射的方式來獲取結(jié)構(gòu)體的tag標簽,遍歷字段的值,修改字段值,調(diào)用結(jié)構(gòu)體方法(要求:通過傳遞地址的方式完成,在前面案例上修改即可)
③定義了兩個函數(shù) test1 和 test2,定義一個適配器函數(shù)用作統(tǒng)一處理接口【了解】
④使用反射操作任意結(jié)構(gòu)體類型?!玖私狻?/p>
⑤使用反射創(chuàng)建并操作結(jié)構(gòu)體。
?