关于Go语言类型相关的内容,大家可以移步 3.1 数据类型 来了解。这一节我们主要讨论类型断言(Type Assertion)的相关内容。
一、什么是类型断言(Type Assertion)
经常地我们对一个接口值的动态类型是不确定的,如方法的形参为接口类型时,此时就需要检验它是否符合我们需要的类型。而Go语言中恰好提供了一个这样的能力来让我们判断类型。类型断言是一个使用在接口值上的操作。
它的语法形式如下:
value, ok := interface{}(x).(T)
赋值符号的右边,是一个类型断言表达式。首先因为断言类型是一个只能使用在接口值上的操作,所以强制将x(变量、字面量或者表达式均可)转换为接口类型。用来检验变量x是否为T类型。赋值符号左边的变量ok是布尔(bool)类型的,它将代表类型判断的结果,true或false。如果是true,那么被判断的值将会被自动转换为T类型的值,并赋给变量value,否则value将被赋予nil(即“空”)。
当然也可以没有“ok”,只有value。但是如果“断言失败”的话,这时候就会引发panic(运行时恐慌)。
value, ok := a.(string)
if !ok {
fmt.Println("It's not ok for type string")
return
}
fmt.Println("The value is ", value)
因为Go语言中,interface{}代表空接口,任何类型都是它的实现类型。
二、如何使用类型断言(Type Assertion)
断言的使用分为两种情况:
- 如果断言的类型T是一个具体类型,类型断言x.(T)就检查x的动态类型是否和T的类型相同。
- 检查成功:类型断言的结果是一个类型为T的对象,该对象的值为接口变量x的动态值。换句话说,具体类型的类型断言从它的操作对象中获得具体的值。
- 检查失败:ok为false,或者只有一个接收变量的时候抛出panic。
- 如果断言的类型T是一个接口类型,类型断言x.(T)检查x的动态类型是否满足T接口。
- 检查成功:则检查结果的接口值的动态类型和动态值不变,但是该接口值的类型被转换为接口类型T。换句话说,对一个接口类型的类型断言改变了类型的表述方式,改变了可以获取的方法集合(通常更大),但是它保护了接口值内部的动态类型和值的部分。
- 检查失败:ok为false,或者只有一个接收变量的时候抛出panic。
针对上面的两种情况,示例代码如下:
//===接口=====
type Tester interface {
getName()string
}
type Tester2 interface {
printName()
}
//===Person类型====
type Person struct {
name string
}
func (p Person)getName() string {
return p.name
}
func (p Person) printName() {
fmt.Println(p.name)
}
//============
func main() {
var t Tester
t = Person{"zhengkai"}
check(t)
}
func check(t Tester) {
//第一种情况
if f, ok1 := t.(Person);ok1 {
fmt.Printf("%T\n%s\n",f,f.getName())
}
//第二种情况
if t, ok2 := t.(Tester2);ok2 { //重用变量名t(无需重新声明)
check2(t) //若类型断言为true,则新的t被转型为Tester2接口类型,但其动态类型和动态值不变
}
}
func check2(t Tester2) {
t.printName()
}
运行结果如下:
main.Person
zhengkai
zhengkai
关于Go语言类型断言的内容就到这里,感谢参考学习。