簡單記錄下平時開發對類型斷言(Type Assertion)的使用場景。golang
golang裏的全部類型都實現了空接口interface{},因此一般將它做爲一個函數的參數或者結構體的字段,以實現對類型的抽象。函數
1.用於轉換函數裏interface{}類型的參數
舉個簡單栗子:code
package main import "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。string
若是不想觸發panic,先作判斷再使用。it
package main import "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.用於轉換結構體的interface{}類型字段
例如,咱們寫handler去接收消息,不可能每一個發來的消息都寫個函數去handle。利用空接口和類型斷言的特性,就能夠將業務抽象出來:io
package main import "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]模板