<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          答應(yīng)我,這次一定徹底搞懂 Go 中的類型別名

          共 2606字,需瀏覽 6分鐘

           ·

          2021-04-07 18:46

          閱讀本文大概需要 5 分鐘。

          大家好,我是站長(zhǎng) polarisxu。

          有下面 3 行代碼:

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

          它們是否能編譯通過?為什么?

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

          01 數(shù)字字面量

          在 Go 語(yǔ)言中,字面量是無類型(untyped)的。無類型是什么意思?無類型意味著可以賦值給類似類型的變量或常量。用上面例子,32.0 是無類型的浮點(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)編譯不通過。

          03 類型別名

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

          type myint int

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

          從 Go1.9 開始引入了類型別名,定義如下:

          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 包。最開始,context 包名是 golang.org/x/net/context,1.7 開始,引入標(biāo)準(zhǔn)庫(kù),這樣一來,存在兩份。Go 1.9 開始采用別名重構(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)出性可以和原類型不一樣;
          • 不能為別的包的類型通過定義別名來增加方法。以下行為是不允許的:
          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

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

          type rune = int32

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

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

          type byte = uint8

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

          04 總結(jié)

          一道看似簡(jiǎn)單的題目,如果你能夠分析透徹,把語(yǔ)言的變化都說出來,我相信面試官會(huì)給你加分。

          今天的題目,你做對(duì)了嗎?




          往期推薦


          歡迎關(guān)注我

          都看到這里了,隨手點(diǎn)個(gè)贊支持下唄!


          瀏覽 91
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91电影一区 | 传媒精品入口 | 91无码人妻精品一区二区三区四 | 骚妇网| 那里有爱爱网站视频 |