加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

go语言类型断言如何引用

发布时间:2023-07-10 14:39:17 所属栏目:语言 来源:
导读:  本篇内容主要讲解“go语言类型断言怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“go语言类型断言怎么使用”吧!

  在go语言
  本篇内容主要讲解“go语言类型断言怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“go语言类型断言怎么使用”吧!
 
  在go语言中,类型断言是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型,语法为“value, ok := x.(T)”。通过类型断言可以做到的事情:1、检查i是否为nil;2、检查i存储的值是否为某个类型。
 
  断言是什么?
 
  断言是编程术语,表示为一些布尔表达。编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设。简单的来理解断言的话就是判断的意思。所以在Go中类型断言我们就可以理解成对类型的判断。
 
  类型断言介绍
 
  类型断言(Type Assertion)是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型。
 
  在Go语言中类型断言的语法格式如下:
 
  value, ok := x.(T)
 
  其中,x 表示一个接口的类型,T 表示一个具体的类型(也可为接口类型)。
 
  该断言表达式会返回 x 的值(也就是 value)和一个布尔值(也就是 ok),可根据该布尔值判断 x 是否为 T 类型:
 
  如果 T 是具体某个类型,类型断言会检查 x 的动态类型是否等于具体类型 T。如果检查成功,类型断言返回的结果是 x 的动态值,其类型是 T。
 
  如果 T 是接口类型,类型断言会检查 x 的动态类型是否满足 T。如果检查成功,x 的动态值不会被提取,返回值是一个类型为 T 的接口值。
 
  无论 T 是什么类型,如果 x 是 nil 接口值,类型断言都会失败。
 
  在Go中类型断言主要有两种形式
 
  变量.(类型)。例如:i.(int)
 
  变量,bool = 变量.(类型)。例如:num,ok = i.(int)。ok表示判断类型是否成功的意思。
 
  类型断言的用法
 
  通过类型断言可以做到以下几件事情
 
  检查 i 是否为 nil
 
  检查 i 存储的值是否为某个类型
 
  具体的使用方式有两种:
 
  第一种:
 
  t := i.(T)
 
  这个表达式可以断言一个接口对象(i)里不是 nil,并且接口对象(i)存储的值的类型是 T,如果断言成功,就会返回值给 t,如果断言失败,就会触发 panic。
 
  来写段代码试验一下
 
  package main
 
  import "fmt"
 
  func main() {
 
      var i interface{} = 10
 
      t1 := i.(int)
 
      fmt.Println(t1)
 
      fmt.Println("=====分隔线=====")
 
      t2 := i.(string)
 
      fmt.Println(t2)
 
  }
 
  运行后输出如下,可以发现在执行第二次断言的时候失败了,并且触发了 panic
 
  10
 
  =====分隔线=====
 
  panic: interface conversion: interface {} is int, not string
 
  goroutine 1 [running]:
 
  main.main()
 
          E:/GoPlayer/src/main.go:12 +0x10e
 
  exit status 2
 
  如果要断言的接口值是 nil,那我们来看看也是不是也如预期一样会触发panic
 
  package main
 
  func main() {
 
      var i interface{} // nil
 
      var _ = i.(interface{})
 
  }
 
  输出如下,确实是会 触发 panic
 
  panic: interface conversion: interface is nil, not interface {}
 
  goroutine 1 [running]:
 
  main.main()
 
          E:/GoPlayer/src/main.go:5 +0x34
 
  exit status 2
 
  第二种
 
  t, ok:= i.(T)
 
  和上面一样,这个表达式也是可以断言一个接口对象(i)里不是 nil,并且接口对象(i)存储的值的类型是 T,如果断言成功,就会返回其类型给 t,并且此时 ok 的值 为 true,表示断言成功。
 
  如果接口值的类型,并不是我们所断言的 T,就会断言失败,但和第一种表达式不同的事,这个不会触发 panic,而是将 ok 的值设为 false ,表示断言失败,此时t 为 T 的零值。
 
  稍微修改下上面的例子,如下
 
  package main
 
  import "fmt"
 
  func main() {
 
      var i interface{} = 10
 
      t1, ok := i.(int)
 
      fmt.Printf("%d-%t\n", t1, ok)
 
      fmt.Println("=====分隔线1=====")
 
      t2, ok := i.(string)
 
      fmt.Printf("%s-%t\n", t2, ok)
 
      fmt.Println("=====分隔线2=====")
 
      var k interface{} // nil
 
      t3, ok := k.(interface{})
 
      fmt.Println(t3, "-", ok)
 
      fmt.Println("=====分隔线3=====")
 
      k = 10
 
      t4, ok := k.(interface{})
 
      fmt.Printf("%d-%t\n", t4, ok)
 
      t5, ok := k.(int)
 
      fmt.Printf("%d-%t\n", t5, ok)
 
  }
 
  运行后输出如下,可以发现在执行第二次断言的时候,虽然失败了,但并没有触发了 panic。
 
  10-true
 
  =====分隔线1=====
 
  -false
 
  =====分隔线2=====
 
  <nil> - false
 
  =====分隔线3=====
 
  10-true
 
  10-true
 
  上面这段输出,你要注意的是第二个断言的输出在-false  之前并不是有没有输出任何 t2 的值,而是由于断言失败,所以 t2 得到的是 string 的零值也是 "" ,它是零长度的,所以你看不到其输出。
 
  Type Switch
 
  如果需要区分多种类型,可以使用 type switch 断言,这个将会比一个一个进行类型断言更简单、直接、高效。
 
  package main
 
  import "fmt"
 
  func findType(i interface{}) {
 
      switch x := i.(type) {
 
      case int:
 
          fmt.Println(x, "is int")
 
      case string:
 
          fmt.Println(x, "is string")
 
      case nil:
 
          fmt.Println(x, "is nil")
 
      default:
 
          fmt.Println(x, "not type matched")
 
      }
 
  }
 
  func main() {
 
      findType(10)      // int
 
      findType("hello") // string
 
      var k interface{} // nil
 
      findType(k)
 
      findType(10.23) //float64
 
  }
 
  输出如下
 
  10 is int
 
  hello is string
 
  <nil> is nil
 
  10.23 not type matched
 
  额外说明一下:
 
  如果你的值是 nil,那么匹配的是 case nil
 
  如果你的值在 switch-case 里并没有匹配对应的类型,那么走的是 default 分支
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!