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

GoLang中的iface?和?eface?的區(qū)別解析

 更新時間:2022年09月30日 14:28:53   作者:~龐貝  
iface 和 eface 都是 Go 中描述接口的底層結(jié)構(gòu)體,區(qū)別在于 iface 描述的接口包含方法,而 eface 則是不包含任何方法的空接口:interface{},這篇文章主要介紹了GoLang之iface?和?eface?的區(qū)別,需要的朋友可以參考下

GoLang之iface 和 eface 的區(qū)別是什么?

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

從源碼層面看一下:

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
}

iface 內(nèi)部維護兩個指針,tab 指向一個 itab 實體, 它表示接口的類型以及賦給這個接口的實體類型。data 則指向接口具體的值,一般而言是一個指向堆內(nèi)存的指針。

再來仔細看一下 itab 結(jié)構(gòu)體:_type 字段描述了實體的類型,包括內(nèi)存對齊方式,大小等;inter 字段則描述了接口的類型。fun 字段放置和接口方法對應(yīng)的具體數(shù)據(jù)類型的方法地址,實現(xiàn)接口調(diào)用方法的動態(tài)分派,一般在每次給接口賦值發(fā)生轉(zhuǎn)換時會更新此表,或者直接拿緩存的 itab。

這里只會列出實體類型和接口相關(guān)的方法,實體類型的其他方法并不會出現(xiàn)在這里。如果你學過 C++ 的話,這里可以類比虛函數(shù)的概念。

另外,你可能會覺得奇怪,為什么 fun 數(shù)組的大小為 1,要是接口定義了多個方法可怎么辦?實際上,這里存儲的是第一個方法的函數(shù)指針,如果有更多的方法,在它之后的內(nèi)存空間里繼續(xù)存儲。從匯編角度來看,通過增加地址就能獲取到這些函數(shù)指針,沒什么影響。順便提一句,這些方法是按照函數(shù)名稱的字典序進行排列的。

再看一下 interfacetype 類型,它描述的是接口的類型:

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

可以看到,它包裝了 _type 類型,_type 實際上是描述 Go 語言中各種數(shù)據(jù)類型的結(jié)構(gòu)體。我們注意到,這里還包含一個 mhdr 字段,表示接口所定義的函數(shù)列表, pkgpath 記錄定義了接口的包名。

這里通過一張圖來看下 iface 結(jié)構(gòu)體的全貌:

iface 結(jié)構(gòu)體全景

接著來看一下 eface 的源碼:

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

相比 iface,eface 就比較簡單了。只維護了一個 _type 字段,表示空接口所承載的具體的實體類型。data 描述了具體的值。

eface 結(jié)構(gòu)體全景

我們來看個例子:

package main

import "fmt"

func main() {
	x := 200
	var any interface{} = x
	fmt.Println(any)

	g := Gopher{"Go"}
	var c coder = g
	fmt.Println(c)
}

type coder interface {
	code()
	debug()
}

type Gopher struct {
	language string
}

func (p Gopher) code() {
	fmt.Printf("I am coding %s language\n", p.language)
}

func (p Gopher) debug() {
	fmt.Printf("I am debuging %s language\n", p.language)
}

執(zhí)行命令,打印出匯編語言:

go tool compile -S ./src/main.go

可以看到,main 函數(shù)里調(diào)用了兩個函數(shù):

func convT2E64(t *_type, elem unsafe.Pointer) (e eface)
func convT2I(tab *itab, elem unsafe.Pointer) (i iface)

上面兩個函數(shù)的參數(shù)和 ifaceeface 結(jié)構(gòu)體的字段是可以聯(lián)系起來的:兩個函數(shù)都是將參數(shù)組裝一下,形成最終的接口。

作為補充,我們最后再來看下 _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
}

Go 語言各種數(shù)據(jù)類型都是在 _type 字段的基礎(chǔ)上,增加一些額外的字段來進行管理的:

type arraytype struct {
	typ   _type
	elem  *_type
	slice *_type
	len   uintptr
}

type chantype struct {
	typ  _type
	elem *_type
	dir  uintptr
}

type slicetype struct {
	typ  _type
	elem *_type
}

type structtype struct {
	typ     _type
	pkgPath name
	fields  []structfield
}

這些數(shù)據(jù)類型的結(jié)構(gòu)體定義,是反射實現(xiàn)的基礎(chǔ)。

到此這篇關(guān)于GoLang之iface 和 eface 的區(qū)別是什么的文章就介紹到這了,更多相關(guān)GoLang iface 和 eface區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • 詳解Go語言中關(guān)于包導入必學的 8 個知識點

    詳解Go語言中關(guān)于包導入必學的 8 個知識點

    這篇文章主要介紹了詳解Go語言中關(guān)于包導入必學的 8 個知識點,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Mango?Cache緩存管理庫TinyLFU源碼解析

    Mango?Cache緩存管理庫TinyLFU源碼解析

    這篇文章主要為大家介紹了Mango?Cache緩存管理庫TinyLFU源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • 詳解Golang time包中的結(jié)構(gòu)體time.Ticker

    詳解Golang time包中的結(jié)構(gòu)體time.Ticker

    在日常開發(fā)過程中,會頻繁遇到對時間進行操作的場景,使用 Golang 中的 time 包可以很方便地實現(xiàn)對時間的相關(guān)操作,接下來的幾篇文章會詳細講解 time 包,本文講解一下 time 包中的結(jié)構(gòu)體 time.Ticker,需要的朋友可以參考下
    2023-08-08
  • 淺析Go中函數(shù)的健壯性,panic異常處理和defer機制

    淺析Go中函數(shù)的健壯性,panic異常處理和defer機制

    這篇文章主要為大家詳細介紹了Go中函數(shù)的健壯性,panic異常處理和defer機制的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2023-10-10
  • Go語言kylin任務(wù)自動化實例詳解

    Go語言kylin任務(wù)自動化實例詳解

    這篇文章主要為大家介紹了Go語言kylin任務(wù)自動化實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 在Go中構(gòu)建并發(fā)TCP服務(wù)器

    在Go中構(gòu)建并發(fā)TCP服務(wù)器

    今天小編就為大家分享一篇關(guān)于在Go中構(gòu)建并發(fā)TCP服務(wù)器的文章,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • 深入理解Golang中的Protocol Buffers及其應(yīng)用

    深入理解Golang中的Protocol Buffers及其應(yīng)用

    本篇文章將深入探討 Go 語言中使用 Protobuf 的基礎(chǔ)知識、常見應(yīng)用以及最佳實踐,希望能幫大家了解如何在項目中高效利用 Protobuf
    2024-11-11
  • 深入解析Sync.Pool如何提升Go程序性能

    深入解析Sync.Pool如何提升Go程序性能

    在并發(fā)編程中,資源的分配和回收是一個很重要的問題。Go?語言的?Sync.Pool?是一個可以幫助我們優(yōu)化這個問題的工具。本篇文章將會介紹?Sync.Pool?的用法、原理以及如何在項目中正確使用它,希望對大家有所幫助
    2023-05-05
  • go語言檢測文件是否存在的方法

    go語言檢測文件是否存在的方法

    這篇文章主要介紹了go語言檢測文件是否存在的方法,實例分析了Go語言文件操作的相關(guān)技巧,需要的朋友可以參考下
    2015-03-03
  • Go語言strconv包實現(xiàn)字符串和數(shù)值類型的相互轉(zhuǎn)換

    Go語言strconv包實現(xiàn)字符串和數(shù)值類型的相互轉(zhuǎn)換

    這篇文章主要介紹了Go語言strconv包實現(xiàn)字符串和數(shù)值類型的相互轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03

最新評論

昌吉市| 朝阳市| 长白| 偃师市| 连云港市| 辉南县| 镇巴县| 砚山县| 涞源县| 石首市| 开江县| 弥渡县| 团风县| 集安市| 三门县| 武夷山市| 荔波县| 察隅县| 绥阳县| 威信县| 封开县| 孝昌县| 厦门市| 闻喜县| 莎车县| 绥阳县| 万年县| 沭阳县| 新河县| 浦北县| 工布江达县| 光泽县| 竹北市| 诸城市| 察隅县| 济源市| 北票市| 正宁县| 锡林浩特市| 桑日县| 无极县|