Go語言的類型轉(zhuǎn)換和類型斷言:
- 類型轉(zhuǎn)換在編譯期完成,包括強(qiáng)制轉(zhuǎn)換和隱式轉(zhuǎn)換
- 類型斷言在運(yùn)行時(shí)確定,包括安全類型斷言和非安全類型斷言
Go語言要求不同類型之間必須做顯式的類型轉(zhuǎn)換。但似乎涉及到接口類型時(shí),就會(huì)有所不同。
//兩種類型斷言
//不安全的類型斷言,如果系統(tǒng)檢測到不匹配,會(huì)在運(yùn)行時(shí)調(diào)用內(nèi)置的panic,拋出異常
s := "abc"
i := s.(int)
//安全的類型斷言。 其中ok為一個(gè)bool值, 表征類型轉(zhuǎn)換是否成功; s為返回的int變量,如果失敗返回該類型的零值
i, ok := s.(int)
1. 類型之間轉(zhuǎn)換
下面是部分例子:
*Point(p) // same as *(Point(p))
(*Point)(p) // p is converted to *Point
<-chan int(c) // same as <-(chan int(c))
(<-chan int)(c) // c is converted to <-chan int
func()(x) // function signature func() x
(func())(x) // x is converted to func()
(func() int)(x) // x is converted to func() int
func() int(x) // x is converted to func() int (unambiguous)
如果不確定符號的優(yōu)先級,可以用括號來約束。
2. 接口之間的轉(zhuǎn)換
接口之間在編譯期間可以確定的情況下可以使用隱式類型轉(zhuǎn)換,當(dāng)然也可以用強(qiáng)制類型轉(zhuǎn)換(不常用),所有情況下都可以使用類型斷言。
type A interface {}
type B interface {Foo()}
// 編譯時(shí)無法確定能不能轉(zhuǎn)換,因此用斷言
var a A
var b = a.(B)
// 編譯時(shí),可以確定
var c B
var d = A(c)
// or var d = c
// or d = c.(A)
3. 接口和類型之間的轉(zhuǎn)換
普通類型向接口轉(zhuǎn)換,可以使用隱式類型轉(zhuǎn)換
type A interface {}
var s = "abc"
var a A
a = s
接口向普通類型轉(zhuǎn)換,只能使用類型斷言,因?yàn)榫幾g器無法確定
type A interface {}
var s string
var a A
s = a.(string)
總結(jié)

type_tab.png
補(bǔ)充一個(gè)例子:
package main
import (
"fmt"
)
func main() {
var e error
defer func() {
if err := recover(); err != nil {
e = err
fmt.Println(e)
}
}()
}
會(huì)報(bào)錯(cuò)
# command-line-arguments
./recover.go:12:15: cannot use err (type interface {}) as type error in assignment:
interface {} does not implement error (missing Error method)
為什么呢?我們可以看一下recover函數(shù)的原型:
func recover() interface{}
原來recover返回的不是error類型,而是空接口,所以編譯時(shí)無法確定能否類型轉(zhuǎn)換。當(dāng)然,類型斷言是可以的。類似的還有panic。
這就告訴我們:名字是err的不一定是error類型,不能以貌取人~