詳解Golang的反射(實(shí)例)

發(fā)布時(shí)間:2024-04-04
下面由golang教程欄目給大家介紹詳解golang的反射(實(shí)例),希望對(duì)需要的朋友有所幫助!
前言
反射在很多語言中都有其妙用。在計(jì)算機(jī)科學(xué)領(lǐng)域,反射是指一類應(yīng)用,它們能夠*自描述*和*自控制*。
本文將記錄筆者對(duì)于golang的反射的筆記。
10s后,以下知識(shí)點(diǎn)即將靠近:
1.反射的簡介
2.為什么使用反射?
3.反射具體能做什么
正文1.反射的簡介
golang提供了一種機(jī)制,在編譯時(shí)不知道類型的情況下,可更新變量、運(yùn)行時(shí)查看值、調(diào)用方法以及直接對(duì)他們的布局進(jìn)行操作的機(jī)制,稱為反射。
2.為什么使用反射?
打個(gè)比方,有時(shí)候我們需要一個(gè)函數(shù)可以處理各種類型的值。在不知道類型的情況下,你可能會(huì)這么寫:
// 偽代碼switch value := value.(type) {case string: // ...一些操作case int: // ...一些操作 case cbsstruct: // 自定義的結(jié)構(gòu)體 // ...一些操作// ...}有沒發(fā)現(xiàn)什么問題?
這邊存在一個(gè)問題:類型很多,這個(gè)函數(shù)會(huì)寫的非常長,而且還可能存在自定的類型,也就是說這個(gè)判斷日后可能還要一直改,因?yàn)闊o法知道未知值到底屬于什么類型。
無法透視一個(gè)未知類型的時(shí)候,以上代碼其實(shí)不是很合理,這時(shí)候就需要有反射來幫忙你處理,反射使用typeof和valueof函數(shù)從接口中獲取目標(biāo)對(duì)象的信息,輕松完成目的。
3.反射具體能做什么?
1.獲取變量內(nèi)部信息
reflect提供了兩種類型來進(jìn)行訪問接口變量的內(nèi)容:
類型作用reflect.valueof()獲取輸入?yún)?shù)接口中的數(shù)據(jù)的值,如果為空則返回0 <- 注意是0reflect.typeof()動(dòng)態(tài)獲取輸入?yún)?shù)接口中的值的類型,如果為空則返回nil <- 注意是nil
上代碼
package mainimport ( "fmt" "reflect")func main() { var name string = "咖啡色的羊駝" // typeof會(huì)返回目標(biāo)數(shù)據(jù)的類型,比如int/float/struct/指針等 reflecttype := reflect.typeof(name) // valueof返回目標(biāo)數(shù)據(jù)的的值,比如上文的"咖啡色的羊駝" reflectvalue := reflect.valueof(name) fmt.println("type: ", reflecttype) fmt.println("value: ", reflectvalue)}輸出:
type: stringvalue: 咖啡色的羊駝更深一層:在以上操作發(fā)生的時(shí)候,反射將“接口類型的變量”轉(zhuǎn)為了“反射的接口類型的變量”,比如上文實(shí)際上返回的是reflect.value和reflect.type的接口對(duì)象。(可以根據(jù)ide跟蹤一下相關(guān)函數(shù)返回類型便知)
2.struct的反射
package mainimport ( "fmt" "reflect")type student struct { id int name string}func (s student) hello(){ fmt.println("我是一個(gè)學(xué)生")}func main() { s := student{id: 1, name: "咖啡色的羊駝"} // 獲取目標(biāo)對(duì)象 t := reflect.typeof(s) // .name()可以獲取去這個(gè)類型的名稱 fmt.println("這個(gè)類型的名稱是:", t.name()) // 獲取目標(biāo)對(duì)象的值類型 v := reflect.valueof(s) // .numfield()來獲取其包含的字段的總數(shù) for i := 0; i < t.numfield(); i { // 從0開始獲取student所包含的key key := t.field(i) // 通過interface方法來獲取key所對(duì)應(yīng)的值 value := v.field(i).interface() fmt.printf("第%d%u4e2a字段是:%s:%v = %v \\\\n", i 1, key.name, key.type, value) } // 通過.nummethod()來獲取student里頭的方法 for i:=0;i<t.nummethod(); i { m := t.method(i) fmt.printf("第%d%u4e2a方法是:%s:%v\\\\n", i 1, m.name, m.type) }}輸出:
這個(gè)類型的名稱是: student第1個(gè)字段是:id:int = 1 第2個(gè)字段是:name:string = 咖啡色的羊駝 第1個(gè)方法是:hello:func(main.student)3.匿名或嵌入字段的反射
package mainimport ( "reflect" "fmt")type student struct { id int name string}type people struct { student // 匿名字段}func main() { p := people{student{id: 1, name: "咖啡色的羊駝"}} t := reflect.typeof(p) // 這里需要加一個(gè)#號(hào),可以把struct的詳情都給打印出來 // 會(huì)發(fā)現(xiàn)有anonymous:true,說明是匿名字段 fmt.printf("%#v\\\\n", t.field(0)) // 取出這個(gè)學(xué)生的名字的詳情打印出來 fmt.printf("%#v\\\\n", t.fieldbyindex([]int{0, 1})) // 獲取匿名字段的值的詳情 v := reflect.valueof(p) fmt.printf("%#v\\\\n", v.field(0))}輸出:
reflect.structfield{name:"student", pkgpath:"", type:(*reflect.rtype)(0x10aade0), tag:"", offset:0x0, index:[]int{0}, anonymous:true}reflect.structfield{name:"name", pkgpath:"", type:(*reflect.rtype)(0x109f4e0), tag:"", offset:0x8, index:[]int{1}, anonymous:false}main.student{id:1, name:"咖啡色的羊駝"}4.判斷傳入的類型是否是我們想要的類型
package mainimport ( "reflect" "fmt")type student struct { id int name string}func main() { s := student{id: 1, name: "咖啡色的羊駝"} t := reflect.typeof(s) // 通過.kind()來判斷對(duì)比的值是否是struct類型 if k := t.kind(); k == reflect.struct { fmt.println("bingo") } num := 1; numtype := reflect.typeof(num) if k := numtype.kind(); k == reflect.int { fmt.println("bingo") }}輸出:
bingobingo5.通過反射修改內(nèi)容
package mainimport ( "reflect" "fmt")type student struct { id int name string}func main() { s := &student{id: 1, name: "咖啡色的羊駝"} v := reflect.valueof(s) // 修改值必須是指針類型否則不可行 if v.kind() != reflect.ptr { fmt.println("不是指針類型,沒法進(jìn)行修改操作") return } // 獲取指針?biāo)赶虻脑?v = v.elem() // 獲取目標(biāo)key的value的封裝 name := v.fieldbyname("name") if name.kind() == reflect.string { name.set
上一個(gè):不銹鋼球閥選型方法
下一個(gè):進(jìn)口寶德隔膜閥安裝維護(hù)

實(shí)驗(yàn)室通風(fēng)柜的重要性
樂鳥分表計(jì)電:大氣污染科學(xué)防治促進(jìn)綠色發(fā)展
氣體校準(zhǔn)過程中的注意事項(xiàng)
二手玻璃反應(yīng)釜
煙熏爐的使用說明
姜糖膏灌裝成套生產(chǎn)線及成套設(shè)備
如何顯示win7用戶名和密碼(win7顯示登錄界面)
電商網(wǎng)站設(shè)計(jì)要注意什么才能吸引用戶
小米手機(jī)字體放在哪個(gè)文件夾(小米手機(jī)的字體下載在哪個(gè)文件夾)
win10專業(yè)版升級(jí)后變成教育版(windows10專業(yè)版變成了教育版)
十八禁 网站在线观看免费视频_2020av天堂网_一 级 黄 色 片免费网站_绝顶高潮合集Videos