零基礎學 Go 語言(40):Go 中四種類型轉換方法

首發自微信公眾號《Go程式設計時光》,如無授權請勿轉載

檢視本系列教程目錄,請點選 零基礎小白入門 Go語言 系列教程

Go 語言是靜態語言,在編寫程式碼時,就對型別有嚴格的要求,一旦型別不匹配,就有可能編譯失敗。

因此在寫程式碼時,就要經常用到型別的轉換,這些知識點,對於一個新手來說,可以說是一個不小的門檻,經常要通常搜尋引擎來尋找答案。

今天我總結了四種日常開發中最經常遇到的型別轉換方法,吃透後就可以自由的進行型別轉換。

第一種:顯式型別轉換

使用對應的型別函式進行轉換,還是以上面的例子來幫助理解,使用 int16 就可以將 int8 型別的物件轉為 int16

package mainimport “fmt”func main() { var a int8 = 5 fmt。Printf(“%T \n”, a) // output: int8 b := int16(a) fmt。Printf(“%T \n”, b) // output: int16}

再舉個例子,先將 string 型別透過 []byte 型別函式轉為 []byte (等同於 []uint8),最後又使用 string 型別函式將 []byte 轉回 string

package mainimport “fmt”func main() { var s1 string = “golang” fmt。Printf(“%T \n”, s1) // output: string s2 := []byte(s1) fmt。Printf(“%T \n”, s2) // output: []uint8 s3 := string(s2) fmt。Printf(“%T \n”, s3) // output: string}

這種方法,同樣適用於自己定義的結構體和介面型別,但要注意的是,

僅能用於將結構體型別轉換介面型別

,而不能將介面型別轉為結構體型別。

這邊也舉個例子

package mainimport “fmt”type People interface { Speak()}type Student struct { name string}func (s Student) Speak() { fmt。Println(“hello, golang”)}func demo2(s People) { s。Speak()}func demo1(s1 Student) { // 結構體型別轉為介面型別 s2 := People(s1) demo2(s2)}func main() { s1 := Student{name: “wangbm”} demo1(s1)}

第二種:隱式型別轉換

隱式轉換,是編譯器所為,在日常開發中,開發者並不會感覺到發生了變化。

隱式轉換以下面兩種情況最為常見,非常簡單,我直接以截圖加標註說明就行了,不再長篇大論。

函式呼叫時轉換

零基礎學 Go 語言(40):Go 中四種類型轉換方法

函式返回時轉換

零基礎學 Go 語言(40):Go 中四種類型轉換方法

第三種:型別斷言

學了上面第二種方法後,我們已經知道下面這段程式碼,肯定是會編譯失敗的。

package mainimport “fmt”type Student struct { name string}func (s Student) Speak() { fmt。Println(“hello, golang”)}func demo2(s Student) { s。Speak()}func demo1(s1 interface{}) { demo2(s1)}func main() { s1 := Student{name: “wangbm”} demo1(s1)}

答案當然是不能了,原因很簡單,因為經過 demo1 函式後,s1 會被隱式轉換成 interface{} 型別,而 demo2 函式的引數型別要求為 Student,因此型別不匹配。

零基礎學 Go 語言(40):Go 中四種類型轉換方法

解決方法也相當的簡單,只要使用型別斷言一下,就能實現靜態型別的轉換。

零基礎學 Go 語言(40):Go 中四種類型轉換方法

為了避免有新手,還不瞭解型別斷言(Type Assertion),我這邊再簡單介紹一下。

型別斷言可用於判斷一個物件是否是某型別。

這其中包含兩種情況:

第一種情況

:該物件是 T 型別(struct 型別),則斷言該物件是 T 型別,就能斷言成功。

第二種情況

:該物件是 I 型別(介面型別),則斷言物件是 T 型別,也能斷言成功,並且返回一個靜態型別為 T 的物件,也相當於型別轉換了。

倘若型別斷言失敗,則會丟擲 panic,使用的時候,請千萬注意處理。若不想讓其丟擲 panic,可以使用另一種斷言語法。斷言不是今天的主題,這裡不再展開,更多具體內容,請檢視我以前的這篇文章 ,寫的非常清楚。

s, ok := x。(T)

另外,有一點需要提醒的是,型別斷言並不能用於兩個通用型別的相互轉換,只能用於將靜態型別為 interface{} 型別的物件,轉為具體的型別。

第四種:重新構造物件

在之前的教程中(詳細圖解:靜態型別與動態型別),我使用圖解,詳細的解釋了 Go 語言中的靜態型別與動態型別。

其中有一個非常重要的知識點,就是如下這種定義變數的方法

package mainimport “fmt”func main() { age := (int)(25) // 等價於 age := 25 fmt。Printf(“type: %T, data: %v ”, age, age) // output: type: int, data: 25}

思路變通一下,這個知識點,也可以應用於型別的轉換。

package mainimport “fmt”func main() { var a int8 = 5 fmt。Printf(“%T \n”, a) // output: int8 b := (int16)(a) fmt。Printf(“%T \n”, b) // output: int16}

以上,就是我總結的四種類型轉換方法,如果你有更多的原生型別轉換方法,歡迎後臺留言告訴我。