类型断言允许我们访问接口中存储的值的数据和数据类型。
在学习类型断言之前,让我们先了解一下 Go 中为什么需要类型断言。
我们知道空接口可以接受任何类型和数量的值。例如,
// create an empty interface
var a interface {}
// store value of string type
a = "Hello World"
// store value of integer type
a = 10
在这里,a 变量是空接口类型,它同时存储了字符串和整数值。要了解更多关于空接口的信息,请访问 Go 空接口。
这似乎是空接口的一个重要特性。然而,有时这会造成接口所包含数据的歧义。
为了消除这种歧义,我们使用类型断言。
示例:Go 类型断言
package main
import "fmt"
func main() {
// create an empty interface
var a interface {}
// store integer to an empty interface
a = 10
// type assertion
interfaceValue := a.(int)
fmt.Println(interfaceValue)
}
输出
10
在上面的示例中,我们将整数值 10 存储到了由 a 表示的空接口中。请注意代码,
interfaceValue := a.(int)
在这里,(int)
检查 a 的值是否为整数。如果为 true
,则将该值赋给 interfaceValue。
否则,程序将恐慌(panic)并终止。例如,
package main
import "fmt"
func main() {
// create an empty interface
var a interface{}
// store integer to an empty interface
a = "Golang"
// type assertion
interfaceValue := a.(int)
fmt.Println(interfaceValue)
}
输出
panic: interface conversion: interface {} is string, not int
在这里,接口的值是字符串。因此,a.(int)
不为 true。所以,程序会恐慌并终止。
要了解更多关于 panic 的信息,请访问 Go panic 语句。
避免 Go 类型断言中的 panic
在 Go 中,类型断言语句实际上会返回一个布尔值以及接口的值。例如,
var a interface {}
a = 12
interfaceValue := a.(int)
在这里,值 12 的数据类型与指定的类型 (int)
匹配,因此此代码将 a 的值赋给 interfaceValue。
除此之外,a.(int)
还返回一个布尔值,我们可以将其存储在另一个变量中。例如,
package main
import "fmt"
func main() {
// create an empty interface
var a interface{}
a = 12
// type assertion
interfaceValue, booleanValue := a.(int)
fmt.Println("Interface Value:", interfaceValue)
fmt.Println("Boolean Value:", booleanValue)
}
输出
Interface Value: 12 Boolean Value: true
在这里,您可以看到我们同时获得了数据和布尔值。
我们可以利用这一点来避免在数据类型与指定类型不匹配时发生 panic。
这是因为,当类型不匹配时,它会返回 false
作为布尔值,因此不会发生 panic。例如,
package main
import "fmt"
func main() {
// create an empty interface
var a interface{}
a = "Golang"
// type assertion
interfaceValue, booleanValue := a.(int)
fmt.Println("Interface Value:", interfaceValue)
fmt.Println("Boolean Value:", booleanValue)
}
输出
Interface Value: 0 Boolean Value: false
在这里,您可以看到我们输出 0 和 false
,因为值 (string)
的数据类型与指定的类型 (int)
不匹配。