runsisi's

technical notes

type assersion vs type switch

2019-03-26 runsisi#golang

Go 没有 C++ 中的重载和模板的概念,在某些情况下,可能会需要通过 interface{} 参数来实现类似的能力,对于 interface{} 类型的变量,不能直接使用类型转换,而需要特殊的 type assertion 或 type switch 语法。

如果需要更细致的控制,可以阅读反射相关的参考资料。

type conversion

Go 类型转换语法与 C 一致,且数值类型之间不支持隐式转换。

var a int = 3
var b64 int64 = 4
b64 = a                 // cannot use a (type int) as type int64 in assignment
b64 = int64(a)          // 3
var c = a + b64         // invalid operation: a + b64 (mismatched types int and int64)

type assertion

如果知道底层类型,可以通过类似 v.(T) 的语法将 interface{} 类型转换成底层具体的类型。

var a interface{} = 3
b := a.(int64)          // panic: interface conversion: interface {} is int, not int64
c, ok := a.(int)        // 3, true
d := a.(int)            // 3

type switch

如果不知道底层类型,则需要使用 v.(type) 结合 switch 进行类型匹配。

var a interface{} = 3
switch v := a.(type) {
case int64:
        fmt.Println("int64:", v)
case string:
        fmt.Println("string:", v)
case int:
        fmt.Println("int:", v)
}                       // int: 3

参考资料

Type assertions in Go

https://medium.com/golangspec/type-assertions-in-go-e609759c42e1

type assertion vs reflection

https://groups.google.com/forum/#!topic/golang-nuts/SGaJ1G4sHtA

Part 34: Reflection

https://golangbot.com/reflection/

The Laws of Reflection

https://blog.golang.org/laws-of-reflection

Go Data Structures: Interfaces

https://research.swtch.com/interfaces