类型断言

* 本页面主要介绍Go语言类型断言这一知识点的相关内容。

关于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语言类型断言的内容就到这里,感谢参考学习。


* 本页内容参考以下数据源:

  • 《Go语言核心36讲》 06 | 程序实体的那些事儿 (下)
  • https://studygolang.com/articles/3314
  • https://www.cnblogs.com/susufufu/archive/2017/08/13/7353290.html

凯冰科技 · 代码改变世界,技术改变生活
Next Page→