" />

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

深入了解Go的interface{}底層原理實現(xiàn)

 更新時間:2022年06月06日 14:23:26   作者:樹獺叔叔  
本文主要介紹了Go的interface{}底層原理實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. interface{}初探

Go是強類型語言,各個實例變量的類型信息正是存放在interface{}中的,Go中的反射也與其底層結(jié)構(gòu)有關(guān)。

ifaceeface 都是 Go 中描述interface{}的底層結(jié)構(gòu)體,區(qū)別在于 iface 描述的接口包含方法,而 eface 則是不包含任何方法的空接口:interface{}

接下來,我們將詳細(xì)剖析ifaceeface的底層數(shù)據(jù)結(jié)構(gòu)。

2. eface

eface 比較簡單,只維護(hù)了 _type 字段,表示空接口所承載的具體的實體類型,以及data 描述了具體的值。

type eface struct {
    _type *_type
    data  unsafe.Pointer
}

data字段是ifaceeface都有的結(jié)構(gòu),這個是一個內(nèi)存指針,指向interface{}實例對象信息的存儲地址,在這里,我們可以獲取對象的具體屬性的數(shù)值信息。

而interface{}的類型信息是存放在_type結(jié)構(gòu)體中的,如下所示,在eface中,直接存放了_type的指針,iface中多了一層封裝,本節(jié)我們主要針對eface做梳理,所以介紹_type結(jié)構(gòu)體。

type _type struct {
    // 類型大小
    size       uintptr
    ptrdata    uintptr
    // 類型的 hash 值
    hash       uint32
    // 類型的 flag,和反射相關(guān)
    tflag      tflag
    // 內(nèi)存對齊相關(guān)
    align      uint8
    fieldalign uint8
    // 類型的編號,有bool, slice, struct 等等等等
    kind       uint8
    alg        *typeAlg
    // gc 相關(guān)
    gcdata    *byte
    str       nameOff
    ptrToThis typeOff
}

我們可以看到size,ptrdata等表示interface{}對象的類型信息,hash是其對應(yīng)的哈希值,用于map等的哈希算法,tflag與反射相關(guān),而alignfieldalign是用來內(nèi)存對齊的,這與Go底層的內(nèi)存管理機制有關(guān),Go的內(nèi)存管理機制類似于Linux中的伙伴系統(tǒng),是以固定大小的內(nèi)存塊進(jìn)行內(nèi)存分配的,與這個大小進(jìn)行對齊消除外碎片,提高內(nèi)存利用率。另外還有一些和gc相關(guān)的參數(shù),大家有一個初步的理解與認(rèn)識就可以了,如果想深入掌握可以專門學(xué)習(xí)和查看源碼。

3. iface

eface不同,iface結(jié)構(gòu)體中要同時儲存方法信息,其數(shù)據(jù)結(jié)構(gòu)如下圖所示。正如前面所說的,itab結(jié)構(gòu)體封裝了_type結(jié)構(gòu)體,同樣利用_type儲存類型信息,另外,其還有一些其他的屬性。hash是對_type結(jié)構(gòu)體中hash的拷貝,提高類型斷言的效率。badinhash都是標(biāo)記位,提高gc以及其他活動的效率。fun指向方法信息的具體地址。

另外,interfacetype,他描述的是接口靜態(tài)類型信息。

fun 字段放置和接口方法對應(yīng)的具體數(shù)據(jù)類型的方法地址,實現(xiàn)接口調(diào)用方法的動態(tài)分派,一般在每次給接口賦值發(fā)生轉(zhuǎn)換時會更新此表,或者直接拿緩存的 itab。這里只會列出實體類型和接口相關(guān)的方法,實體類型的其他方法并不會出現(xiàn)在這里。如果你學(xué)過 C++ 的話,這里可以類比虛函數(shù)的概念,至于靜態(tài)函數(shù),并不存放在這里。

C++ 和 Go 在定義接口方式上的不同,也導(dǎo)致了底層實現(xiàn)上的不同。C++ 通過虛函數(shù)表來實現(xiàn)基類調(diào)用派生類的函數(shù);而 Go 通過 itab 中的 fun 字段來實現(xiàn)接口變量調(diào)用實體類型的函數(shù)。C++ 中的虛函數(shù)表是在編譯期生成的;而 Go 的 itab 中的 fun 字段是在運行期間動態(tài)生成的。原因在于,Go 中實體類型可能會無意中實現(xiàn) N 多接口,很多接口并不是本來需要的,所以不能為類型實現(xiàn)的所有接口都生成一個 itab, 這也是“非侵入式”帶來的影響;這在 C++ 中是不存在的,因為派生需要顯示聲明它繼承自哪個基類。

type iface struct {
    tab  *itab
    data unsafe.Pointer
}

type itab struct {
    inter  *interfacetype
    _type  *_type
    link   *itab
    hash   uint32 // copy of _type.hash. Used for type switches.
    bad    bool   // type does not implement interface
    inhash bool   // has this itab been added to hash?
    unused [2]byte
    fun    [1]uintptr // variable sized
}

type interfacetype struct {
    typ     _type
    pkgpath name
    mhdr    []imethod
}

綜合上面的分析,我們可以梳理出,iface對應(yīng)的幾個重要數(shù)據(jù)結(jié)構(gòu)的關(guān)系如下圖所示。

4. 接口轉(zhuǎn)化

通過前面提到的 iface 的源碼可以看到,實際上它包含接口的類型 interfacetype 和 實體類型的類型 _type,這兩者都是 iface 的字段 itab 的成員。也就是說生成一個 itab 同時需要接口的類型和實體的類型。

->itable

當(dāng)判定一種類型是否滿足某個接口時,Go 使用類型的方法集和接口所需要的方法集進(jìn)行匹配,如果類型的方法集完全包含接口的方法集,則可認(rèn)為該類型實現(xiàn)了該接口。

例如某類型有 m 個方法,某接口有 n 個方法,則很容易知道這種判定的時間復(fù)雜度為 O(mn),Go 會對方法集的函數(shù)按照函數(shù)名的字典序進(jìn)行排序,所以實際的時間復(fù)雜度為 O(m+n)。

Go的接口實現(xiàn)是非侵入式的,而是鴨子模式:如果某個東西長得像鴨子,像鴨子一樣游泳,像鴨子一樣嘎嘎叫,那它就可以被看成是一只鴨子。

因此,只要我們實現(xiàn)了接口對應(yīng)的方法,也就實現(xiàn)了對應(yīng)的接口,不需要單獨申明。

到此這篇關(guān)于深入了解Go的interface{}底層原理實現(xiàn)的文章就介紹到這了,更多相關(guān)Go interface{}底層原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang設(shè)計模式之組合模式講解

    Golang設(shè)計模式之組合模式講解

    這篇文章主要介紹了Golang設(shè)計模式之組合模式,組合模式針對于特定場景,如文件管理、組織管理等,使用該模式能簡化管理,使代碼變得非常簡潔
    2023-01-01
  • Go語言JSON編解碼神器之marshal的運用

    Go語言JSON編解碼神器之marshal的運用

    這篇文章主要為大家詳細(xì)介紹了Go語言中JSON編解碼神器——marshal的運用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • 使用go連接clickhouse方式

    使用go連接clickhouse方式

    這篇文章主要介紹了使用go連接clickhouse方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Go語言與其他語言進(jìn)行交互的方式詳解

    Go語言與其他語言進(jìn)行交互的方式詳解

    在當(dāng)今的軟件開發(fā)領(lǐng)域,多種編程語言常常需要協(xié)同工作,以充分利用各自的優(yōu)勢來構(gòu)建復(fù)雜的應(yīng)用系統(tǒng),Go 語言作為一門高效、簡潔的編程語言,也經(jīng)常需要與其他語言進(jìn)行交互,接下來,我們將詳細(xì)探討 Go 語言如何與其他語言進(jìn)行交互,需要的朋友可以參考下
    2024-06-06
  • Go語言中的反射原理解析與應(yīng)用

    Go語言中的反射原理解析與應(yīng)用

    反射(Reflection)是計算機科學(xué)中的一個重要概念,它允許程序在運行時檢查變量和值,獲取它們的類型信息,并且能夠修改它們,本文將結(jié)合實際案例,詳細(xì)介紹Go語言中反射的基本概念、關(guān)鍵函數(shù)以及使用場景,需要的朋友可以參考下
    2024-10-10
  • Go語言讀取,設(shè)置Cookie及設(shè)置cookie過期方法詳解

    Go語言讀取,設(shè)置Cookie及設(shè)置cookie過期方法詳解

    這篇文章主要介紹了Go語言讀取,設(shè)置Cookie及設(shè)置cookie過期方法詳解,需要的朋友可以參考下
    2022-04-04
  • GPT回答:go語言和C語言切片對比

    GPT回答:go語言和C語言切片對比

    這篇文章主要為大家介紹了GPT回答:go語言和C語言切片對比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Golang?gRPC?HTTP協(xié)議轉(zhuǎn)換示例

    Golang?gRPC?HTTP協(xié)議轉(zhuǎn)換示例

    這篇文章主要為大家介紹了Golang?gRPC?HTTP協(xié)議轉(zhuǎn)換示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 深入理解Go語言中的Dispatcher

    深入理解Go語言中的Dispatcher

    最近看到了Go語言中的Dispatcher,但是在網(wǎng)上發(fā)現(xiàn)資料非常少,所以想著總結(jié)處理分享給大家,下面這篇文章主要給大家深入的介紹Go語言中Dispatcher的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-03-03
  • Go語言學(xué)習(xí)之操作MYSQL實現(xiàn)CRUD

    Go語言學(xué)習(xí)之操作MYSQL實現(xiàn)CRUD

    Go官方提供了database包,database包下有sql/driver。該包用來定義操作數(shù)據(jù)庫的接口,這保證了無論使用哪種數(shù)據(jù)庫,操作方式都是相同的。本文就來和大家聊聊Go語言如何操作MYSQL實現(xiàn)CRUD,希望對大家有所幫助
    2023-02-02

最新評論

万安县| 廉江市| 武安市| 青铜峡市| 福鼎市| 阿图什市| 新余市| 敦化市| 自治县| 讷河市| 白河县| 湘乡市| 札达县| 密山市| 西宁市| 米泉市| 前郭尔| 齐齐哈尔市| 铁力市| 开鲁县| 九台市| 泰顺县| 浦北县| 延安市| 清苑县| 池州市| 响水县| 凤阳县| 永寿县| 石门县| 扬州市| 麟游县| 开封市| 沁水县| 平武县| 岳阳县| 葫芦岛市| 上思县| 长垣县| 宣武区| 小金县|