<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>

          Golang 類(lèi)型斷言 vs 類(lèi)型轉(zhuǎn)換

          共 2931字,需瀏覽 6分鐘

           ·

          2021-01-16 20:08

          這是一篇譯文,原文出處:https://www.sohamkamani.com/golang/type-assertions-vs-type-conversions/。


          Go中,類(lèi)型斷言和類(lèi)型轉(zhuǎn)換是一個(gè)令人困惑的事情,他們似乎都在做同樣的事情。

          這篇文章,我們將看到類(lèi)型斷言和類(lèi)型轉(zhuǎn)換實(shí)際上是如何截然不同的,并深入了解在Go中使用它們會(huì)發(fā)生什么。

          首先,讓我們看看它們長(zhǎng)什么樣……

          下面是一個(gè)類(lèi)型斷言的例子:

          var greeting interface{} = "hello world"greetingStr := greeting.(string)

          接著看一個(gè)類(lèi)型轉(zhuǎn)換的例子:

          greeting := []byte("hello world")greetingStr := string(greeting)

          最明顯的不同點(diǎn)是他們具有不同的語(yǔ)法(variable.(type) vs type(variable) )。接下來(lái),我們進(jìn)一步去研究。



          類(lèi)型斷言

          顧名思義,類(lèi)型斷言用于斷言變量是屬于某種類(lèi)型。類(lèi)型斷言只能發(fā)生在interface{}類(lèi)型上。
          上面類(lèi)型斷言的例子,
          greeting是一個(gè)interface{}類(lèi)型,我們?yōu)槠浞峙淞艘粋€(gè)字符串。現(xiàn)在,我們可以認(rèn)為greeting實(shí)際上是一個(gè)string,但是對(duì)外展示的是一個(gè)interface{}
          如果我們想獲取greeting的原始類(lèi)型,那么我們可以斷言它是個(gè)string,并且此斷言操作會(huì)返回其string類(lèi)型。


          這意味著在做類(lèi)型斷言的時(shí)候,我們應(yīng)該知道任何變量的基礎(chǔ)類(lèi)型。但是情況并非總是這樣的,這就是為什么類(lèi)型斷言操作實(shí)際上還返回了第二個(gè)可選值的原因。

          var greeting interface{} = "42"greetingStr, ok := greeting.(string)

          第二個(gè)值是一個(gè)布爾值,如果斷言正確,返回?true?,否則返回?false
          另外,類(lèi)型斷言是在程序運(yùn)行時(shí)執(zhí)行。


          類(lèi)型判斷

          類(lèi)型判斷是一個(gè)很實(shí)用的構(gòu)造。當(dāng)你不確定interface{}真正類(lèi)型的時(shí)候,可以使用它。

          var greeting interface{} = 42
          switch g := greeting.(type) { case string: fmt.Println("g is a string with length", len(g)) case int: fmt.Println("g is an integer, whose value is", g) default: fmt.Println("I don't know what g is")}


          為什么需要斷言

          在上面的例子中,我們似乎在將greetinginterface{}轉(zhuǎn)換成int類(lèi)型或者string類(lèi)型。但是greeting的類(lèi)型是固定,并且和初始化期間聲明時(shí)的內(nèi)容一樣。
          當(dāng)我們把greeting分配給interface{}類(lèi)型的時(shí)候,請(qǐng)勿修改其原始類(lèi)型。同樣,當(dāng)我們斷言類(lèi)型的時(shí)候,我們只是使用了原始類(lèi)型功能,而不是使用interface公開(kāi)的有限方法。


          類(lèi)型轉(zhuǎn)換

          首先,我們花點(diǎn)時(shí)間了解一下什么是 “類(lèi)型”。在 Go?每種類(lèi)型都定義了兩件事:

          • 變量的存儲(chǔ)方式 (存儲(chǔ)結(jié)構(gòu))

          • 你可以使用變量做什么 (可以使用的方法和函數(shù))

          這里介紹了基本類(lèi)型,包括了stringint。以及一些復(fù)合類(lèi)型,比如structmaparrayslice

          你可以從基本類(lèi)型或通過(guò)創(chuàng)建復(fù)合類(lèi)型來(lái)聲明一個(gè)新類(lèi)型。

          // `myInt` 是一個(gè)新類(lèi)型,它的基類(lèi)型是 `int`type myInt int
          // AddOne 方法適用于 `myInt` 類(lèi)型,不適用于 `int` 類(lèi)型func (i myInt) AddOne() myInt { return i + 1}
          func main() { var i myInt = 4 fmt.Println(i.AddOne())}

          當(dāng)我們聲明一個(gè)myInt類(lèi)型,我們可以將變量數(shù)據(jù)基于基本的int類(lèi)型,但是如果要進(jìn)行變量修改,我們可以通過(guò)myInt類(lèi)型變量進(jìn)行操作 (通過(guò)在myInt上面聲明一個(gè)新方法)。

          由于myInt?的類(lèi)型基于int,意味著他們的底層基礎(chǔ)類(lèi)型是一樣的。因此這些類(lèi)型的變量可以相互轉(zhuǎn)換。

           var i myInt = 4originalInt := int(i)

          上面i的類(lèi)型是myInt,originalInt的類(lèi)型是int



          什么時(shí)候使用類(lèi)型轉(zhuǎn)換?

          只有當(dāng)基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)類(lèi)型相同,類(lèi)型之間才可以相互轉(zhuǎn)換。來(lái)看一個(gè)使用struct例子。

          type person struct {    name string    age int}
          type child struct { name string age int}
          type pet { name string}
          func main() { bob := person{ name: "bob", age: 15, } babyBob := child(bob) // "babyBob := pet(bob)" 會(huì)導(dǎo)致編譯錯(cuò)誤 fmt.Println(bob, babyBob)}

          在這里,person?和 child?擁有相同的數(shù)據(jù)結(jié)構(gòu),即:

          struct {    name string    age int}

          因此他們可以相互轉(zhuǎn)換。


          type可用于聲明具有相同數(shù)據(jù)結(jié)構(gòu)的多種類(lèi)型。

          type?pet?person

          這只是意味著childperson基于相同的數(shù)據(jù)結(jié)構(gòu) (類(lèi)似于之前的intmyInt)。


          類(lèi)型為什么稱(chēng)為轉(zhuǎn)換

          就像上面說(shuō)的,雖然不同類(lèi)型的基礎(chǔ)結(jié)構(gòu)可能相同,但是他們可能也具有不同的限制和方法。當(dāng)我們從一種類(lèi)型轉(zhuǎn)換成另一種類(lèi)型時(shí),會(huì)改變對(duì)類(lèi)型的處理方式,而不是像類(lèi)型斷言那樣僅公開(kāi)其基礎(chǔ)類(lèi)型,這就是他們本質(zhì)的差別。(ps:這句話是我自己加的)。
          如果嘗試去轉(zhuǎn)換錯(cuò)誤的類(lèi)型,類(lèi)型轉(zhuǎn)換會(huì)提示編譯錯(cuò)誤,這和類(lèi)型斷言所提供的運(yùn)行時(shí)通過(guò)返回值判斷錯(cuò)誤,完全相反。


          類(lèi)型結(jié)論

          類(lèi)型斷言和類(lèi)型轉(zhuǎn)換有著比語(yǔ)法層面上更根本的區(qū)別。它還強(qiáng)調(diào)了在Go中接口類(lèi)型 (interface) 和非接口類(lèi)型之間的區(qū)別。

          接口類(lèi)型沒(méi)有任何數(shù)據(jù)結(jié)構(gòu),而是公開(kāi)了已有的具體類(lèi)型 (具有底層數(shù)據(jù)結(jié)構(gòu)) 的一些方法。
          類(lèi)型斷言引出了接口的具體類(lèi)型,而類(lèi)型轉(zhuǎn)換改變了在具有相同數(shù)據(jù)結(jié)構(gòu)的兩個(gè)具體類(lèi)型之間使用變量的方式。



          推薦閱讀


          福利

          我為大家整理了一份從入門(mén)到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門(mén)看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù)?ebook?獲取;還可以回復(fù)「進(jìn)群」,和數(shù)萬(wàn) Gopher 交流學(xué)習(xí)。

          瀏覽 30
          點(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>
                  国产极品人妖ts91热爆 | 麻豆成人网一区二区 | 一区二区三区中文字幕 | 无码三级在线播放 | 草逼操 |