一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - Golang 內存模型詳解(一)

Golang 內存模型詳解(一)

2019-11-28 17:24Golang教程網 Golang

這篇文章主要介紹了Golang 內存模型詳解(一),本文講解了Go內存模型interface、,需要的朋友可以參考下

開始之前

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

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

此 nil 不等彼 nil

先聲明,這個標題有標題黨的嫌疑。

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

 

復制代碼代碼如下:

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 ", ai == nil)
    fmt.Printf("ai == ei: %v ", ai == ei)
    fmt.Printf("ei == a: %v ", a == ei)
    fmt.Printf("ei == nil: %v ", ei == nil)
}
// -> 輸出
// ai == nil: false
// ai == ei: false
// ei == a: false
// ei == nil: true

 

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

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

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

Go 內存模型 - interface

概述

為了讀懂下面的內容,你需要:

了解 C、Go 語言

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

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

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

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

1.runtime.h
2.type.h

對于 interface 類型,主要看下面幾個結構體定義:

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

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

InterfaceType:

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

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

 

復制代碼代碼如下:

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

 

Itab:

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

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

 

復制代碼代碼如下:

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

 

Iface:

該類型為一般的 interface 類型所對應的數據結構,其中:

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

 

復制代碼代碼如下:

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

 

Eface:

該類型為 interface{} (empty interface) 所對應的數據結構,其中:

1.type: 具體實現類型, 也即 receiver type
2.data: 同 Iface

 

復制代碼代碼如下:

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

 

他們的依賴關系如下圖所示:

Golang 內存模型詳解(一)

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

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

延伸 · 閱讀

精彩推薦
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
主站蜘蛛池模板: 日本久久啪啪婷婷激情五月 | 免费岛国片 | 青青成人| 国产视频播放 | 日本 在线播放 | 亚洲日日做天天做日日谢 | 天堂精品高清1区2区3区 | 色妞女女女女女bbbb | 国模李丽莎大尺度啪啪 | 男人机机桶女人机机 | 四虎网址大全 | 99爱免费视频 | 深夜影院深a | 操美女网址 | 男人猛激烈吃奶gif动态图 | 天堂成人在线 | 九九在线精品视频 | 91av最新地址| 手机国产乱子伦精品视频 | japanesexxxx在线播放| 男男gaygays中国 | 天天操天天干天天 | 72张让男人一看就硬的图片 | 九九热免费在线观看 | 亚洲一区二区三区不卡在线播放 | 5g影院天天影院天天爽影院网站 | 四虎e234hcom | 久久久精品免费视频 | 亚洲男人的天堂网 | 亚洲a视频在线观看 | 色中色软件 | 四虎影院在线 | 情侣奴伺候女王第2部分小说 | 国内精品久久久久影院网站 | a级片欧美 | 女同性互吃奶乳免费视频 | 国产成人综合久久 | 青青青手机在线视频 | 垫底辣妹免费观看完整版 | 99草精品视频 | 无人在线观看免费高清视频播放 |