這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
簡單記錄下平時開發對類型斷言(Type Assertion)的使用情境。
1.用於轉換函式裡interface{}類型的參數
golang裡的所有類型都實現了空介面interface{},所以通常將它作為一個函數的抽象類別型的參數。舉個簡單栗子:
package mainimport "fmt"func main() { add(1, 2) add(int16(1), int16(2)) add(float32(1.1), float32(2.2)) add(float64(1.1), float64(2.2)) add(true, false)}func add(a, b interface{}) { switch t := a.(type) { case int: fmt.Printf("type [%T] add res[%d]\n", t, a.(int)+b.(int)) case int16: fmt.Printf("type [%T] add res[%d]\n", t, a.(int16)+b.(int16)) case float32: fmt.Printf("type [%T] add res[%f]\n", t, a.(float32)+b.(float32)) case float64: fmt.Printf("type [%T] add res[%f]\n", t, a.(float64)+b.(float64)) default: fmt.Printf("type [%T] not support!\n", t) }}
輸出結果:
type [int] add res[3]
type [int16] add res[3]
type [float32] add res[3.300000]
type [float64] add res[3.300000]
type [bool] not support!
用interface{}作參數,是不是很像C++的模板函數,而類型斷言是不是很像C++的類層次間的下行轉換(也是不一定成功的)。需要注意的是,a.(type)只能和switch搭配使用。在使用前得用斷言指明變數的類型,如果斷言錯誤就會觸發panic。
如果不想觸發panic,先做判斷再使用。
package mainimport "fmt"func main() { a := int16(2) b := int32(3) add(a, b)}func add(a, b interface{}) { _, ok := a.(int32) if !ok { fmt.Println("error type assertion!") } b = b}
運行結果:
error type assertion!
2.作為結構體的欄位類型使用
例如,我們寫handler去接收訊息,不可能每個發來的訊息都寫個函數去handle。利用空介面和類型斷言的特性,就可以將業務抽象出來:
package mainimport "fmt"import "time"type NetMsg struct { MsgID int16 Data interface{}}type Cat struct { name string age int16}type Dog struct { name string age int32}type human struct { name string age int64}func main() { msg1 := NetMsg{1, Cat{"Qian", 1}} msg2 := NetMsg{2, Dog{"doge", 8}} msg3 := NetMsg{3, Dog{"allu", 18}} msg_handler(msg1) time.Sleep(2000 * time.Millisecond) msg_handler(msg2) time.Sleep(2000 * time.Millisecond) msg_handler(msg3)}func msg_handler(msg NetMsg) { switch msg.MsgID { case 1: cat := msg.Data.(Cat) fmt.Printf("Do Something with Msg 1 %v \n", cat) case 2: dog := msg.Data.(Dog) fmt.Printf("Do Something with Msg 2 %v \n", dog) default: fmt.Printf("Error MsgID [%d] \n", msg.MsgID) }}
運行結果:
Do Something with Msg 1 {Qian 1}
Do Something with Msg 2 {doge 8}
Error MsgID [3]