日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

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

 F2967527 2021-04-24

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

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

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

首先,讓我們看看它們長什么樣……

下面是一個類型斷言的例子:

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

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

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

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

類型斷言

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

圖片

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

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

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

類型判斷

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

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類型或者string類型。但是greeting的類型是固定,并且和初始化期間聲明時的內(nèi)容一樣。
當(dāng)我們把greeting分配給interface{}類型的時候,請勿修改其原始類型。同樣,當(dāng)我們斷言類型的時候,我們只是使用了原始類型功能,而不是使用interface公開的有限方法。


類型轉(zhuǎn)換

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

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

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

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

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

// `myInt` 是一個新類型,它的基類型是 `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)我們聲明一個myInt類型,我們可以將變量數(shù)據(jù)基于基本的int類型,但是如果要進(jìn)行變量修改,我們可以通過myInt類型變量進(jìn)行操作 (通過在myInt上面聲明一個新方法)。

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

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

上面i的類型是myInt,originalInt的類型是int。

圖片

什么時候使用類型轉(zhuǎn)換?

只有當(dāng)基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)類型相同,類型之間才可以相互轉(zhuǎn)換。來看一個使用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)' 會導(dǎo)致編譯錯誤 fmt.Println(bob, babyBob)}

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

struct {    name string    age int}

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

圖片


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

type pet person

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

類型為什么稱為轉(zhuǎn)換

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


類型結(jié)論

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

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



    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多