最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

揭秘Go語(yǔ)言中的反射機(jī)制

 更新時(shí)間:2023年10月25日 08:38:39   作者:Shasha^^  
在Go語(yǔ)言中,反射是通過(guò)reflect包來(lái)實(shí)現(xiàn)的,通過(guò)使用反射,我們可以在運(yùn)行時(shí)獲取對(duì)象的類型信息、訪問(wèn)對(duì)象的字段和方法、動(dòng)態(tài)調(diào)用方法等,反射在很多場(chǎng)景下都非常有用,比如編寫(xiě)通用的代碼、實(shí)現(xiàn)對(duì)象的序列化和反序列化、實(shí)現(xiàn)依賴注入等,需要的朋友可以參考下

基本概念

支持反射的語(yǔ)言可以在程序編譯期將變量的反射信息,如字段名稱、類型信息、結(jié)構(gòu)體信息等整合到可執(zhí)行文件中,并給程序提供接口訪問(wèn)反射信息,這樣就可以在程序運(yùn)行期獲取類型的反射信息,并且有能力修改它們。

Go語(yǔ)言提供了 reflect 包來(lái)訪問(wèn)程序的反射信息。

Refelct解析

Refelct包 定義了兩個(gè)重要的類型 Type 和 Value,任意接口在反射中都可以理解為 由 reflect.Type 和 reflect.Value 兩部分組成 。簡(jiǎn)單來(lái)說(shuō),go 的接口是由兩部分組成的,一部分是類型信息,另一部分是數(shù)據(jù)信息

eg

var a=1
var b interface{}=a

對(duì)于 這個(gè)例子,b 的類型信息是 int,數(shù)據(jù)信息是 1,這兩部分信息都是存儲(chǔ)在 b 里面的。b 的內(nèi)存結(jié)構(gòu)如下:

而 b實(shí)際上是一個(gè)空接口,也就是說(shuō)一個(gè) interface{} 中實(shí)際上既包含了變量的類型信息,也包含了類型的數(shù)據(jù)

refelct.Type ,refelct.Value
如上所說(shuō),所有的接口都含有type 和value ,我們可以使用refelct包中的 typeof 和valueof將信息從接口中取出

var a = 1
t := reflect.TypeOf(a)

var b = "hello"
t1 := reflect.ValueOf(b)

反射定律

三條反射定律 :

  1. 反射可以將 interface 類型變量轉(zhuǎn)換成反射對(duì)象。
  2. 反射可以將反射對(duì)象還原成 interface 對(duì)象。
  3. 如果要修改反射對(duì)象,那么反射對(duì)象必須是可設(shè)置的(CanSet)。

將 interface 類型變量轉(zhuǎn)換成反射對(duì)象

我們可以通過(guò) reflect.TypeOf 和 reflect.ValueOf 來(lái)獲取到一個(gè)變量的反射類型和反射值。

var a = 1
typeOfA := reflect.TypeOf(a)
valueOfA := reflect.ValueOf(a)

將反射對(duì)象還原成 interface 對(duì)象。

我們可以通過(guò) reflect.Value.Interface 來(lái)獲取到反射對(duì)象的 interface 對(duì)象,也就是傳遞給 reflect.ValueOf 的那個(gè)變量本身。 不過(guò)返回值類型是 interface{},所以我們需要進(jìn)行類型斷言。

i := valueOfA.Interface()
fmt.Println(i.(int))

修改反射對(duì)象

通過(guò) reflect.Value.CanSet 來(lái)判斷一個(gè)反射對(duì)象是否是可設(shè)置的。如果是可設(shè)置的,我們就可以通過(guò) reflect.Value.Set 來(lái)修改反射對(duì)象的值。

var x float64 = 3.4
v := reflect.ValueOf(&x)
fmt.Println("settability of v:", v.CanSet()) // false
fmt.Println("settability of v:", v.Elem().CanSet()) // true

那什么情況下一個(gè)反射對(duì)象是可設(shè)置的呢?前提是這個(gè)反射對(duì)象是一個(gè)指針,然后這個(gè)指針指向的是一個(gè)可設(shè)置的變量 .

在上面這個(gè)例子中,v.CanSet() 返回的是 false,而 v.Elem().CanSet() 返回的是 true。

在這里,v是一根指針,但是v.Elem()才是v這根指針指向的值。Elem方法是一個(gè)解引用的作用。對(duì)于這個(gè)指針本身,我們修改它是沒(méi)有意義的,我們可以設(shè)想一下, 如果我們修改了指針變量(也就是修改了指針變量指向的地址),那會(huì)發(fā)生什么呢?那樣我們的指針變量就不是指向 x 了, 而是指向了其他的變量,這樣就不符合我們的預(yù)期了。所以 v.CanSet() 返回的是 false。

而 v.Elem().CanSet() 返回的是 true。這是因?yàn)?v.Elem() 才是 x 本身,通過(guò) v.Elem() 修改 x 的值是沒(méi)有問(wèn)題的


Elem()

refelct.Value中的Elem

reflect.Value 的 Elem 方法的作用是獲取指針指向的值,或者獲取接口的動(dòng)態(tài)值。

對(duì)于指針很好理解,其實(shí)作用類似解引用。而對(duì)于接口,還是要回到 interface 的結(jié)構(gòu)本身,因?yàn)榻涌诶锇祟愋秃蛿?shù)據(jù)本身,所以 Elem 方法就是獲取接口的數(shù)據(jù)部分(也就是 iface 或 eface 中的 data 字段)。

refelct.Type中的Elem

reflect.Type 的 Elem 方法的作用是獲取數(shù)組、chan、map、指針、切片關(guān)聯(lián)元素的類型信息,也就是說(shuō),對(duì)于 reflect.Type 來(lái)說(shuō), 能調(diào)用 Elem 方法的反射對(duì)象,必須是數(shù)組、chan、map、指針、切片中的一種,其他類型的 reflect.Type 調(diào)用 Elem 方法會(huì) panic。

t1 := reflect.TypeOf([3]int{1, 2, 3}) // 數(shù)組 [3]int
fmt.Println(t1.String()) // [3]int
fmt.Println(t1.Elem().String()) // int

需要注意的是,如果我們要獲取 map 類型 key 的類型信息,需要使用 Key 方法,而不是 Elem 方法。

m := make(map[string]string)
t1 := reflect.TypeOf(m)
fmt.Println(t1.Key().String()) // string

反射是Go語(yǔ)言中一種強(qiáng)大的編程技術(shù),它允許程序在運(yùn)行時(shí)動(dòng)態(tài)地檢查和修改對(duì)象的結(jié)構(gòu)和行為。通過(guò)使用reflect包,我們可以在運(yùn)行時(shí)獲取對(duì)象的類型信息、訪問(wèn)對(duì)象的字段和方法、動(dòng)態(tài)調(diào)用方法等。反射在很多場(chǎng)景下都非常有用,比如編寫(xiě)通用的代碼、實(shí)現(xiàn)對(duì)象的序列化和反序列化、實(shí)現(xiàn)依賴注入等。然而,反射的使用也需要謹(jǐn)慎,因?yàn)樗鼤?huì)帶來(lái)一定的性能損耗。在實(shí)際開(kāi)發(fā)中,我們應(yīng)該根據(jù)具體的需求來(lái)判斷是否需要使用反射??偟膩?lái)說(shuō),反射是Go語(yǔ)言中一個(gè)非常有用的特性,它為我們提供了更大的靈活性和擴(kuò)展性。

到此這篇關(guān)于揭秘Go語(yǔ)言中的反射機(jī)制的文章就介紹到這了,更多相關(guān)Go語(yǔ)言反射機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang反射獲取結(jié)構(gòu)體的值和修改值的代碼示例

    Golang反射獲取結(jié)構(gòu)體的值和修改值的代碼示例

    這篇文章主要給大家介紹了golang反射獲取結(jié)構(gòu)體的值和修改值的代碼示例及演示效果,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,感興趣的同學(xué)可以參考閱讀本文
    2023-08-08
  • go語(yǔ)言Pflag Viper Cobra 核心功能使用介紹

    go語(yǔ)言Pflag Viper Cobra 核心功能使用介紹

    這篇文章主要為大家介紹了go語(yǔ)言Pflag Viper Cobra 核心功能使用介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Go語(yǔ)言遍歷循環(huán)的幾種方法

    Go語(yǔ)言遍歷循環(huán)的幾種方法

    遍歷循環(huán)主要用于迭代數(shù)組、切片、映射(map)、字符串等數(shù)據(jù)結(jié)構(gòu),本文主要介紹了Go語(yǔ)言遍歷循環(huán)的幾種方法,下面就來(lái)介紹一下,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-03-03
  • 教你用go語(yǔ)言實(shí)現(xiàn)比特幣交易功能(Transaction)

    教你用go語(yǔ)言實(shí)現(xiàn)比特幣交易功能(Transaction)

    每一筆比特幣交易都會(huì)創(chuàng)造輸出,輸出都會(huì)被區(qū)塊鏈記錄下來(lái)。給某個(gè)人發(fā)送比特幣,實(shí)際上意味著創(chuàng)造新的 UTXO 并注冊(cè)到那個(gè)人的地址,可以為他所用,今天通過(guò)本文給大家分享go語(yǔ)言實(shí)現(xiàn)比特幣交易功能,一起看看吧
    2021-05-05
  • 詳解如何修改Go結(jié)構(gòu)體的私有字段

    詳解如何修改Go結(jié)構(gòu)體的私有字段

    在 Go 語(yǔ)言中,結(jié)構(gòu)體字段的訪問(wèn)權(quán)限是由字段名的首字母決定的:首字母大寫(xiě)表示公共字段(public),首字母小寫(xiě)表示私有字段(private),本文給大家介紹了如何修改Go結(jié)構(gòu)體的私有字段,需要的朋友可以參考下
    2025-01-01
  • Go語(yǔ)言范圍Range的實(shí)現(xiàn)示例

    Go語(yǔ)言范圍Range的實(shí)現(xiàn)示例

    range是Go語(yǔ)言中一個(gè)非常有用的功能,它可以幫助我們更方便地遍歷各種類型的序列,通過(guò)本文的介紹,相信你已經(jīng)對(duì)range有了一定的了解,感興趣的可以了解一下
    2025-10-10
  • Golang使用ttl機(jī)制保存內(nèi)存數(shù)據(jù)方法詳解

    Golang使用ttl機(jī)制保存內(nèi)存數(shù)據(jù)方法詳解

    ttl(time-to-live) 數(shù)據(jù)存活時(shí)間,我們這里指數(shù)據(jù)在內(nèi)存中保存一段時(shí)間,超過(guò)期限則不能被讀取到,與Redis的ttl機(jī)制類似。本文僅實(shí)現(xiàn)ttl部分,不考慮序列化和反序列化
    2023-03-03
  • go語(yǔ)言實(shí)現(xiàn)猜數(shù)字小游戲的方法

    go語(yǔ)言實(shí)現(xiàn)猜數(shù)字小游戲的方法

    這篇文章主要介紹了go語(yǔ)言實(shí)現(xiàn)猜數(shù)字小游戲的方法,實(shí)例分析了Go語(yǔ)言流程判斷與處理的技巧,需要的朋友可以參考下
    2015-03-03
  • Go語(yǔ)言實(shí)現(xiàn)Sm2加解密的示例代碼

    Go語(yǔ)言實(shí)現(xiàn)Sm2加解密的示例代碼

    本文主要介紹了Go語(yǔ)言實(shí)現(xiàn)Sm2加解密的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Go語(yǔ)言死鎖與goroutine泄露問(wèn)題的解決

    Go語(yǔ)言死鎖與goroutine泄露問(wèn)題的解決

    最近在工作中使用golang編程,今天的文章給大家分享一下Go語(yǔ)言死鎖與goroutine泄露問(wèn)題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評(píng)論

宁化县| 东方市| 佳木斯市| 江川县| 泽库县| 洪江市| 屏边| 宁强县| 商水县| 兴隆县| 望奎县| 睢宁县| 石楼县| 临颍县| 措美县| 九龙城区| 苗栗县| 綦江县| 固镇县| 木兰县| 安岳县| 五寨县| 鹤庆县| 河曲县| 邹平县| 商丘市| 台中市| 巢湖市| 民县| 镇远县| 高雄县| 渑池县| 海宁市| 鹤山市| 蒙自县| 巴彦县| 连平县| 呼图壁县| 海口市| 白山市| 五大连池市|