麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Golang > 正文

Golang 內(nèi)存模型詳解(一)

2020-04-01 19:25:51
字體:
供稿:網(wǎng)友
這篇文章主要介紹了Golang 內(nèi)存模型詳解(一),本文講解了Go內(nèi)存模型interface、,需要的朋友可以參考下
 

開始之前

首先,這是一篇菜B寫的文章,可能會有理解錯誤的地方,發(fā)現(xiàn)錯誤請斧正,謝謝。

為了治療我的懶癌早期,我一次就不寫得太多了,這個系列想寫很久了,每次都是開了個頭就沒有再寫。這次爭取把寫完,弄成一個系列。

此 nil 不等彼 nil

先聲明,這個標(biāo)題有標(biāo)題黨的嫌疑。

Go 的類型系統(tǒng)是比較奇葩的,nil 的含義跟其它語言有些差別,這里舉個例子(可以直接進入 http://play.golang.org/p/ezFhXX0dnB 運行查看結(jié)果):

 

復(fù)制代碼代碼如下:

package main
import "fmt"
type A struct {
}
func main() {
    var a *A = nil
    var ai interface{} = a
    var ei interface{} = nil
    fmt.Printf("ai == nil: %v/n", ai == nil)
    fmt.Printf("ai == ei: %v/n", ai == ei)
    fmt.Printf("ei == a: %v/n", a == ei)
    fmt.Printf("ei == nil: %v/n", ei == nil)
}
// -> 輸出
// ai == nil: false
// ai == ei: false
// ei == a: false
// ei == nil: true

 

這里 ai != nil,對于沒有用過 Go 的人來說比較費解,對我來說,這個算得上一門語言設(shè)計有歧義的地方(Golang FAQ 有對于此問題的描述,可以參考一下:http://golang.org/doc/faq#nil_error)。

簡單的說就是 nil 代表 “zero value”(空值),對于不同類型,它具體所代表的值不同。比如上面的 a 為“*A 類型的空值”,而 ai 為“interface{} 類型的空值”。造成理解失誤的最大問題在于,struct pointer 到 interface 有隱式轉(zhuǎn)換(var ai interface{] = a,這里有個隱式轉(zhuǎn)換),至于為什么對于 Go 這種在其它轉(zhuǎn)換方面要求嚴(yán)格,而對于 interface 要除外呢,for convenience 吧,呵呵……

碰到了這個坑,我就開始好奇了,Go 的類型系統(tǒng)到底是什么樣的?

Go 內(nèi)存模型 - interface

概述

為了讀懂下面的內(nèi)容,你需要:

了解 C、Go 語言

Go 1.3 源代碼 (https://go.googlecode.com/archive/go1.3.zip)

PS: 由于 Go 用到了 Plan9 C 這個小眾的C編譯器的擴展,比如在函數(shù)簽名中使用 · 字符以區(qū)分 package/function(比如runtime·panic),這對理解不會產(chǎn)生什么影響。

PSS: 對于 Go runtime,可以參考src/pkg/reflect(reflect包)中的的代碼,對類型系統(tǒng)的實現(xiàn)的理解有幫助。

Go 語言的類型定義可以在 src/pkg/runtime/ 目錄下找到,主要由以下幾個文件構(gòu)成:

1.runtime.h
2.type.h

對于 interface 類型,主要看下面幾個結(jié)構(gòu)體定義:

1.InterfaceType
2.Itab
3.Iface
4.Eface

它們的C語言定義如下 (可以在 runtime.h 中找到):

InterfaceType:

代表了總的 interface 類型,其中:

1.Type: 類型描述,所有的類型都有這個類型描述(比如 array, map, slice)
2.mhdr 以及 m: interface 接口方法列表

 

復(fù)制代碼代碼如下:

struct InterfaceType
{
    Type;
    Slice mhdr;
    IMethod m[];
};

 

Itab:

類似于虛函數(shù)表,該表不會被GC回收,其中:

1.inter: 指向具體的 interface 類型
2.type: 具體實現(xiàn)類型, 也即 receiver type
3.link: 指向下一個函數(shù)表,因為 interface 可以 embed 多個 interface,因此實現(xiàn)為一個鏈表形式
4.bad: <略>
5.unsued: <略>
6.fun: 函數(shù)列表,每個元素是一個指向具體函數(shù)實現(xiàn)的指針

 

復(fù)制代碼代碼如下:

struct  Itab
{
    InterfaceType*  inter;
    Type*   type;
    Itab*   link;
    int32   bad;
    int32   unused;
    void    (*fun[])(void);
};

 

Iface:

該類型為一般的 interface 類型所對應(yīng)的數(shù)據(jù)結(jié)構(gòu),其中:

1.tab: 參見 Itab 的說明,尤其是 Itab::link
2.data: 指向具體數(shù)據(jù)(比如指向struct,當(dāng)然,如果一個數(shù)據(jù)不超過一個字長,那么這個data就可以直接存放,不需要指針再做以及跳轉(zhuǎn))

 

復(fù)制代碼代碼如下:

struct Iface
{
    Itab*   tab;
    void*   data;
};

 

Eface:

該類型為 interface{} (empty interface) 所對應(yīng)的數(shù)據(jù)結(jié)構(gòu),其中:

1.type: 具體實現(xiàn)類型, 也即 receiver type
2.data: 同 Iface

 

復(fù)制代碼代碼如下:

struct Eface
{
    Type*   type;
    void*   data;
};

 

他們的依賴關(guān)系如下圖所示:

Golang 內(nèi)存模型詳解(一)

先到這里,下一篇將會舉例子說明給一個 interface{} 類型的變量賦值后,其具體的內(nèi)存結(jié)構(gòu)是怎么樣的。

打了幾個小時,真費時間,爭取這個系列不坑 (逃


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美日韩在线视频一区二区 | 国产在线精品一区二区不卡 | 狠狠操夜夜爱 | 欧美不卡视频在线观看 | 一区二区三区在线观看视频 | 爽爽淫人综合网网站 | 鲁丝片一区二区三区免费入口 | 欧美三级日本三级少妇99 | 91精品久久久久久久 | 羞羞羞网站 | 国产午夜免费福利 | 亚洲免费视频一区 | 一本视频在线观看 | 2017亚洲男人天堂 | 黄色高清免费 | 国产刺激高潮av | 久久艹国产精品 | 538任你躁在线精品视频网站 | 亚洲射逼 | 亚洲国产精久久久久久久 | 欧美成人一区二区三区电影 | 天天舔夜夜操 | 九色一区二区 | 丰满年轻岳中文字幕一区二区 | 午夜爽爽爽男女免费观看hd | 羞羞草视频 | 2017亚洲男人天堂 | jizzzxxxxhd | 欧美a v在线 | 欧美18一12sex性处hd | 国产成人自拍视频在线 | 免费试看av| 久久久久夜色精品国产老牛91 | 久久人体 | 成人一区二区三区在线 | 日本黄色不卡视频 | 亚洲精品一区二区三区免 | 午夜视频亚洲 | 免费观看高清视频网站 | 九九热在线精品视频 | 色视频在线播放 |