一文帶你了解Go語(yǔ)言中的類型斷言和類型轉(zhuǎn)換
在Go
中,類型斷言和類型轉(zhuǎn)換是一個(gè)令人困惑的事情,他們似乎都在做同樣的事情。
下面是一個(gè)類型斷言的例子:
var greeting interface{} = "hello world" greetingStr := greeting.(string)
接著看一個(gè)類型轉(zhuǎn)換的例子:
greeting := []byte("hello world") greetingStr := string(greeting)
最明顯的不同點(diǎn)是他們具有不同的語(yǔ)法(variable.(type) vs type(variable) )
。接下來(lái),我們進(jìn)一步去研究。
類型斷言
顧名思義,類型斷言用于斷言變量是屬于某種類型。類型斷言只能發(fā)生在interface{}
類型上。
上面類型斷言的例子,greeting
是一個(gè)interface{}
類型,我們?yōu)槠浞峙淞艘粋€(gè)字符串?,F(xiàn)在,我們可以認(rèn)為greeting
實(shí)際上是一個(gè)string
,但是對(duì)外展示的是一個(gè)interface{}
。
如果我們想獲取greeting
的原始類型,那么我們可以斷言它是個(gè)string
,并且此斷言操作會(huì)返回其string
類型。
這意味著在做類型斷言的時(shí)候,我們應(yīng)該知道任何變量的基礎(chǔ)類型。但是情況并非總是這樣的,這就是為什么類型斷言操作實(shí)際上還返回了第二個(gè)可選值的原因。
var greeting interface{} = "42" greetingStr, ok := greeting.(string)
第二個(gè)值是一個(gè)布爾值,如果斷言正確,返回 true ,否則返回 false。
另外,類型斷言是在程序運(yùn)行時(shí)執(zhí)行。
類型判斷
類型判斷是一個(gè)很實(shí)用的構(gòu)造。當(dāng)你不確定interface{}
真正類型的時(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") }
為什么需要斷言
在上面的例子中,我們似乎在將greeting
從interface{}
轉(zhuǎn)換成int
類型或者string
類型。但是greeting
的類型是固定,并且和初始化期間聲明時(shí)的內(nèi)容一樣。
當(dāng)我們把greeting
分配給interface{}
類型的時(shí)候,請(qǐng)勿修改其原始類型。同樣,當(dāng)我們斷言類型的時(shí)候,我們只是使用了原始類型功能,而不是使用interface
公開(kāi)的有限方法。
類型轉(zhuǎn)換
首先,我們花點(diǎn)時(shí)間了解一下什么是 “類型”。在 Go 每種類型都定義了兩件事:
- 變量的存儲(chǔ)方式 (存儲(chǔ)結(jié)構(gòu))
- 你可以使用變量做什么 (可以使用的方法和函數(shù))
這里介紹了基本類型,包括了string
和int
。以及一些復(fù)合類型,比如struct``map``array
和slice
。 你可以從基本類型或通過(guò)創(chuàng)建復(fù)合類型來(lái)聲明一個(gè)新類型。
// `myInt` 是一個(gè)新類型,它的基類型是 `int` type myInt int // AddOne 方法適用于 `myInt` 類型,不適用于 `int` 類型 func (i myInt) AddOne() myInt { return i + 1} func main() { var i myInt = 4 fmt.Println(i.AddOne()) }
當(dāng)我們聲明一個(gè)myInt
類型,我們可以將變量數(shù)據(jù)基于基本的int
類型,但是如果要進(jìn)行變量修改,我們可以通過(guò)myInt
類型變量進(jìn)行操作 (通過(guò)在myInt
上面聲明一個(gè)新方法)。 由于myInt
的類型基于int
,意味著他們的底層基礎(chǔ)類型是一樣的。因此這些類型的變量可以相互轉(zhuǎn)換。
var i myInt = 4 originalInt := int(i)
上面i
的類型是myInt
,originalInt
的類型是int
。
什么時(shí)候使用類型轉(zhuǎn)換
只有當(dāng)基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)類型相同,類型之間才可以相互轉(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)的多種類型。 這只是意味著child
和person
基于相同的數(shù)據(jù)結(jié)構(gòu) (類似于之前的int
和myInt
)。
類型為什么稱為轉(zhuǎn)換
就像上面說(shuō)的,雖然不同類型的基礎(chǔ)結(jié)構(gòu)可能相同,但是他們可能也具有不同的限制和方法。當(dāng)我們從一種類型轉(zhuǎn)換成另一種類型時(shí),會(huì)改變對(duì)類型的處理方式,而不是像類型斷言那樣僅公開(kāi)其基礎(chǔ)類型,這就是他們本質(zhì)的差別。
如果嘗試去轉(zhuǎn)換錯(cuò)誤的類型,類型轉(zhuǎn)換會(huì)提示編譯錯(cuò)誤,這和類型斷言所提供的運(yùn)行時(shí)通過(guò)返回值判斷錯(cuò)誤,完全相反。
類型結(jié)論
類型斷言和類型轉(zhuǎn)換有著比語(yǔ)法層面上更根本的區(qū)別。它還強(qiáng)調(diào)了在Go
中接口類型 (interface
) 和非接口類型之間的區(qū)別。 接口類型沒(méi)有任何數(shù)據(jù)結(jié)構(gòu),而是公開(kāi)了已有的具體類型 (具有底層數(shù)據(jù)結(jié)構(gòu)) 的一些方法。
類型斷言引出了接口的具體類型,而類型轉(zhuǎn)換改變了在具有相同數(shù)據(jù)結(jié)構(gòu)的兩個(gè)具體類型之間使用變量的方式。
到此這篇關(guān)于一文帶你了解Go語(yǔ)言中的類型斷言和類型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Go類型斷言 類型轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang 實(shí)現(xiàn)對(duì)Map進(jìn)行鍵值自定義排序
這篇文章主要介紹了golang 實(shí)現(xiàn)對(duì)Map進(jìn)行鍵值自定義排序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04Go 1.22對(duì)net/http包的路由增強(qiáng)功能詳解
Go 1.22 版本對(duì) net/http 包的路由功能進(jìn)行了增強(qiáng),引入了方法匹配(method matching)和通配符(wildcards)兩項(xiàng)新功能,本文將給大家詳細(xì)的介紹一下Go 1.22對(duì)net/http包的路由增強(qiáng)功能,需要的朋友可以參考下2024-02-02Golang安裝和使用protocol-buffer流程介紹
這篇文章主要介紹了Golang安裝和使用protocol-buffer過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09Go?內(nèi)聯(lián)優(yōu)化讓程序員愛(ài)不釋手
這篇文章主要介紹了Go?內(nèi)聯(lián)優(yōu)化讓程序員愛(ài)不釋手,內(nèi)聯(lián)是在編譯過(guò)程中自動(dòng)進(jìn)行的一類基本優(yōu)化之一,文章圍繞主題展開(kāi)更多詳細(xì)介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06golang中實(shí)現(xiàn)graphql請(qǐng)求的方法
這篇文章主要介紹了如何在golang中實(shí)現(xiàn)graphql請(qǐng)求,在本文中,我們介紹了如何使用gqlgen來(lái)構(gòu)建GraphQL服務(wù),需要的朋友可以參考下2023-04-04Go?modules?replace解決Go依賴引用問(wèn)題
這篇文章主要為大家介紹了Go?modules?replace解決Go依賴引用問(wèn)題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06