如何理解Go中的類型別名

這篇文章主要介紹“如何理解Go中的類型別名”,在日常操作中,相信很多人在如何理解Go中的類型別名問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”如何理解Go中的類型別名”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

成都做網(wǎng)站、網(wǎng)站建設(shè)的關(guān)注點(diǎn)不是能為您做些什么網(wǎng)站,而是怎么做網(wǎng)站,有沒(méi)有做好網(wǎng)站,給成都創(chuàng)新互聯(lián)一個(gè)展示的機(jī)會(huì)來(lái)證明自己,這并不會(huì)花費(fèi)您太多時(shí)間,或許會(huì)給您帶來(lái)新的靈感和驚喜。面向用戶友好,注重用戶體驗(yàn),一切以用戶為中心。

有下面 3 行代碼:

// 32 位機(jī)器 1)var x int32 = 32.0 2)var y int = x 3)var z rune = x

它們是否能編譯通過(guò)?為什么?

如果面試時(shí)問(wèn)這道題,你需要想想面試官想考察你什么。在往下看之前,建議你記下自己的答案。

01 數(shù)字字面量

在 Go 語(yǔ)言中,字面量是無(wú)類型(untyped)的。無(wú)類型是什么意思?無(wú)類型意味著可以賦值給類似類型的變量或常量。用上面例子,32.0  是無(wú)類型的浮點(diǎn)數(shù)字面量,因此它可以賦值給任意數(shù)字相關(guān)類型變量(或常量)。以下都是合法的:

var a int64 = 32.0 var b int = 32.0 var c float32 = 32.0 var d complex64 = 32.0 var e byte = 32.0 var f rune = 32.0

所以上題中 1)是正確的。

02 不同類型

在目前 Go 1.16 版本中(實(shí)際上只有很早期的版本不是),int 類型在 32 位機(jī)器占 4 字節(jié),64 位機(jī)器占 8 字節(jié)。所以,在 32  位機(jī)器上,int32 和 int 的內(nèi)存占用和內(nèi)存布局是完全一樣的。但 Go 語(yǔ)言不會(huì)做隱式類型轉(zhuǎn)換,int 和 int32 是不同的類型,因此上題中  2)編譯不通過(guò)。

03 類型別名

熟悉 C 語(yǔ)言的小伙伴,看到 Go 中以下定義:

type myint int

會(huì)以為 myint 和 int 是一樣的,認(rèn)為 myint 是 int 的別名。而實(shí)際上,myint 是和 int 完全不一樣的類型,只不過(guò) myint  的底層類型是 int,它們直接可以強(qiáng)制類型轉(zhuǎn)換,卻不會(huì)隱式轉(zhuǎn)換。關(guān)于這點(diǎn)無(wú)需多講,重點(diǎn)要講的是類型別名。

從 Go1.9 開(kāi)始引入了類型別名,定義如下:

AliasDecl = identifier, "=", Type .

具體例子:

type intalias = int

myint 是新類型,和 int 不一樣;而 intalias 卻和 int 一樣,它只是 int 的別名:所有使用 intalias 的地方都可以使用  int。

那為什么 Go 中會(huì)引入類型別名呢?Russ Cox 的論文 Codebase Refactoring (with help from Go)  介紹了它的背景。總結(jié)一下類型別名的用途,主要有兩點(diǎn):

  • 在大規(guī)模重構(gòu)項(xiàng)目代碼的時(shí)候,尤其是將一個(gè)類型從一個(gè)包移動(dòng)到另一個(gè)包中的時(shí)候,有些代碼會(huì)使用新包中的類型,有些代碼使用舊包中的類型, 最典型的是  context 包。最開(kāi)始,context 包名是 golang.org/x/net/context,1.7 開(kāi)始,引入標(biāo)準(zhǔn)庫(kù),這樣一來(lái),存在兩份。Go 1.9  開(kāi)始采用別名重構(gòu)了它;

  • 允許一個(gè)龐大的包分解成內(nèi)部的幾個(gè)小包,但是小包中的類型需要集中暴漏在上層的大包中;

在 Go 中,你可以為任意類型定義別名,比如數(shù)組、結(jié)構(gòu)體、指針、函數(shù)、接口、Slice、Map、Channel 等,包括為自定義類型定義別名。

type F = func() type I = interface{} ...

此外,還可以為其他包中的類型定義別名,比如為標(biāo)準(zhǔn)庫(kù)類型定義別名:

type MyReader = bufio.Reader

關(guān)于類型別名的一些注意事項(xiàng):

  • 別名和原類型是一樣的,因此 switch-type 結(jié)構(gòu)中,不能存在兩個(gè) case,一個(gè)是原類型,一個(gè)是別名;

  • 類型別名不能循環(huán)定義,比如以下是不允許的:

type T = struct {  next *T1 }  type T1 = T
  • 因?yàn)閯e名和原類型是一樣的,因此共享同樣的方法集,不論這個(gè)方法是定義在原類型還是別名上;

  • 別名的導(dǎo)出性可以和原類型不一樣;

  • 不能為別的包的類型通過(guò)定義別名來(lái)增加方法。以下行為是不允許的:

type MyReader = bufio.Reader func (MyReader) AliasMethod() {  fmt.Println("This is alias method") }

編譯報(bào)錯(cuò):cannot define new methods on non-local type bufio.Reader。

回到開(kāi)頭題目的 3),rune 是什么類型?定義如下:

type rune = int32

很顯然,rune 是 int32 的別名,因此題目中 3)也能編譯通過(guò)。

除了 rune,Go 內(nèi)置類型中,還有 byte 是 uint8 的別名:

type byte = uint8

需要說(shuō)明的是,在 Go1.9 之前,rune 和 byte 的別名性質(zhì)就存在,是編譯器負(fù)責(zé)處理的。只是 Go1.9 之后,別名可以用于其他類型了。

到此,關(guān)于“如何理解Go中的類型別名”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

分享名稱:如何理解Go中的類型別名
當(dāng)前網(wǎng)址:http://muchs.cn/article14/ijsdde.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣品牌網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站Google、虛擬主機(jī)、小程序開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)