成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go語言之再談空接口

開發(fā) 后端
Go編譯器可以把任何類型的數(shù)據(jù)封裝成該結(jié)構(gòu)的對象;結(jié)果是在語法層面, interface{} 類型的變量可以引用任何類型的數(shù)據(jù), interface{} 類型的形式參數(shù)可以接收任何類型的實(shí)際參數(shù)。

[[430589]]

前言

在 【Go】內(nèi)存中的空接口 一文中,我們知道 interface{} 類型的對象的結(jié)構(gòu)如下:

  1. // emptyInterface is the header for an interface{} value. 
  2. type emptyInterface struct { 
  3.   typ  *rtype 
  4.   word unsafe.Pointer 

該結(jié)構(gòu)體包含兩個(gè)指針,占 16 個(gè)字節(jié)。

該結(jié)構(gòu)體包含類型信息和數(shù)據(jù)信息,Go編譯器可以把任何類型的數(shù)據(jù)封裝成該結(jié)構(gòu)的對象;結(jié)果是在語法層面, interface{} 類型的變量可以引用任何類型的數(shù)據(jù), interface{} 類型的形式參數(shù)可以接收任何類型的實(shí)際參數(shù)。

前文只是介紹了 interface{} 的對象結(jié)構(gòu),但還沒有介紹 interface{} 的類型信息。本文將詳細(xì)分析空接口的類型信息。

繼續(xù)閱讀文本之前,強(qiáng)烈推薦優(yōu)先閱讀以下兩篇圖文:

  • 【Go】內(nèi)存中的空接口
  • 【Go】深入理解函數(shù)

環(huán)境

  1. OS : Ubuntu 20.04.2 LTS; x86_64 
  2. Go : go version go1.16.2 linux/amd64 

聲明

操作系統(tǒng)、處理器架構(gòu)、Go版本不同,均有可能造成相同的源碼編譯后運(yùn)行時(shí)的寄存器值、內(nèi)存地址、數(shù)據(jù)結(jié)構(gòu)等存在差異。

本文僅包含 64 位系統(tǒng)架構(gòu)下的 64 位可執(zhí)行程序的研究分析。

本文僅保證學(xué)習(xí)過程中的分析數(shù)據(jù)在當(dāng)前環(huán)境下的準(zhǔn)確有效性。

代碼清單

  1. package main 
  2.  
  3. import "fmt" 
  4. import "reflect" 
  5.  
  6. func main() { 
  7.   Typeof(Typeof) 
  8.  
  9. //go:noinline 
  10. func Typeof(i interface{}) { 
  11.   t := reflect.TypeOf(i) 
  12.   fmt.Println("函數(shù)類型", t.String()) 
  13.   fmt.Println("參數(shù)類型", t.In(0).String()) 

運(yùn)行結(jié)果

接口類型

接口類型信息的結(jié)構(gòu)定義在reflect/type.go源文件中:

  1. // interfaceType represents an interface type. 
  2. type interfaceType struct { 
  3.   rtype 
  4.   pkgPath name      // import path 
  5.   methods []imethod // sorted by hash 

該結(jié)構(gòu)體占 80 個(gè)字節(jié)。

結(jié)構(gòu)分布圖

將接口類型信息繪制成圖表如下:

內(nèi)存分析

再次強(qiáng)調(diào),繼續(xù)之前務(wù)必閱讀 【Go】內(nèi)存中的函數(shù) ,方便了解本文分析過程。

定義Typeof函數(shù)的目的是方便定位 interface{} 的類型信息,直接在該函數(shù)入口處設(shè)置斷點(diǎn)。

在調(diào)試過程中,首先得到的是Typeof函數(shù)的類型信息。該函數(shù)只有一個(gè)參數(shù),參數(shù)的類型信息位于內(nèi)存地址 0x4a5200 處,這就是空接口的類型信息。

將空接口的類型信息做成圖表如下:

  • rtype.size = 16
  • rtype.ptrdata = 16
  • rtype.hash = 0x18a057e7
  • rtype.tflag = 2 = reflect.tflagExtraStar
  • rtype.align = 8
  • rtype.fieldAlign = 8
  • rtype.kind = 20 = reflect.Interface
  • rtype.equal = 0x4c2ba8 = runtime.nilinterequal
  • rtype.str = 0x000030b0 => *interface {}
  • rtype.ptrToThis = 0x000067c0
  • interfaceType.pkgPath = 0 = nil
  • interfaceType.methods.Data = 0x4a5220
  • interfaceType.methods.Len = 0
  • interfaceType.methods.Cap = 0

從以上數(shù)據(jù)我們可以知道,interface{} 類型的對象 16 字節(jié)大小、8 字節(jié)對齊、具有可比較性,沒有任何方法。

ptrToThis = 0x000067c0 是空接口指針類型(*interface{})信息的內(nèi)存偏移量。

空接口是Go語言內(nèi)置的數(shù)據(jù)類型,不屬于任何包,所以包路徑值為空(pkgPath)。

可比較性

空接口具有可比較性。

空接口類型的equal函數(shù)為runtime.nilinterequal,該函數(shù)定義在runtime/alg.go源文件中:

  1. func nilinterequal(p, q unsafe.Pointer) bool { 
  2.   x := *(*eface)(p) 
  3.   y := *(*eface)(q) 
  4.   return x._type == y._type && efaceeq(x._type, x.data, y.data) 
  5.  
  6. func efaceeq(t *_type, x, y unsafe.Pointer) bool { 
  7.   if t == nil { 
  8.     return true 
  9.   } 
  10.   eq := t.equal 
  11.   if eq == nil { 
  12.     panic(errorString("comparing uncomparable type " + t.string())) 
  13.   } 
  14.   if isDirectIface(t) { 
  15.     return x == y 
  16.   } 
  17.   return eq(x, y) 
  18. // isDirectIface reports whether t is stored directly in an interface value. 
  19. func isDirectIface(t *_type) bool { 
  20.   return t.kind&kindDirectIface != 0 

通過源碼,看到空接口對象比較的邏輯如下:

  1. 如果兩個(gè)對象的類型不一樣,返回 false
  2. 如果兩個(gè)對象的類型一樣,并且值為nil,返回 true
  3. 如果兩個(gè)對象的類型一樣,但是不可比較,直接 panic
  4. 然后進(jìn)行比較,并返回比較結(jié)果。

也就是說,空接口對象的比較,實(shí)際是其表示的類型和其指向的數(shù)據(jù)的比較。

通過內(nèi)存中的空接口和本文,基本已經(jīng)全面了解了 interface{}。

本文轉(zhuǎn)載自微信公眾號「Golang In Memory」

 

責(zé)任編輯:姜華 來源: Golang In Memory
相關(guān)推薦

2021-10-03 22:18:14

Go語言整數(shù)

2020-12-31 09:06:44

Go語言Reflect

2021-10-16 17:53:35

Go函數(shù)編程

2021-10-09 07:52:01

Go程序重命名

2022-03-28 13:34:26

Go泛型部署泛型

2019-01-03 09:45:20

Go 前端 Web

2024-01-05 20:46:14

2013-08-20 10:11:20

Go系統(tǒng)管理員

2021-05-12 08:53:54

Go語言調(diào)度

2021-10-18 10:53:26

Go 代碼技術(shù)

2024-01-08 08:23:07

Go語言代碼

2013-07-10 11:11:05

PythonGo語言

2012-08-13 14:13:46

2017-06-14 09:37:05

R語言Apriori算法

2012-02-13 10:03:31

編程開發(fā)

2018-08-01 15:10:02

GolangPython語言

2013-02-19 09:26:17

2018-03-12 22:13:46

GO語言編程軟件

2010-01-14 10:34:02

C++語言

2011-05-13 15:54:50

C模塊化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲一区二区在线播放 | 一区二区免费在线 | 日日夜夜天天综合 | 日韩成人免费在线视频 | 天天操夜夜爽 | 久久精品综合网 | 欧美精品久久 | 亚洲精品乱码久久久久久蜜桃91 | h片在线看 | 亚洲不卡视频 | 成人在线免费电影 | 久久蜜桃av一区二区天堂 | 国产一区二区三区高清 | 日本天堂视频在线观看 | 午夜影院污 | 蜜桃精品在线 | 小h片免费观看久久久久 | 久久精品综合 | 黄免费观看| 午夜影院网站 | 欧美一区免费 | 美女国产 | 在线日韩不卡 | 欧美一级大片免费看 | 久久不卡视频 | 伊人精品视频 | 中文字幕在线一 | 久久免费国产视频 | 精品伊人| 在线a视频网站 | 精品国产91乱码一区二区三区 | 伊人性伊人情综合网 | 国产精品色哟哟网站 | 少妇av片 | 免费视频一区二区三区在线观看 | 大乳boobs巨大吃奶挤奶 | 成人精品国产一区二区4080 | 久久亚洲一区二区三 | 欧美日韩一区二区在线观看 | 亚洲精品日韩综合观看成人91 | 91精品国产综合久久久久 |