一起聊聊go语言中的类型断言

GO语言中的类型断言是什么?答:类型断言是一个编程术语,主要使用在接口值上,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型,语法为“value, ok := x.(T)”。通过类型断言可以做到的事情:1、检查i是否为nil;2、检查i存储的值是否为某个类型。


一起聊聊go语言中的类型断言


一起聊聊go语言中的类型断言


断言是一个编程术语,表示为一些布尔表达,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型。在编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设。简单的来理解断言的话就是判断的意思。所以在Go中类型断言我们就可以理解成对类型的判断。


在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


以上就是关于go语言中的类型断言之解析,翼速应用平台内有更多相关资讯,欢迎查阅!


我来说两句

0 条评论

推荐阅读

  • 响应式布局CSS媒体查询设备像素比介绍

    构建响应式网站布局最常见的是流体网格,灵活调整大小的站点布局技术,确保用户在使用的幕上获得完整的体验。响应式设计如何展示富媒体图像,可以通过以下几种方法。

    admin
  • 提升网站的性能快速加载的实用技巧

    网站速度很重要,快速加载的网站会带来更好的用户体验、更高的转化率、更多的参与度,而且在搜索引擎排名中也扮演重要角色,做SEO,网站硬件是起跑线,如果输在了起跑线,又怎么跟同行竞争。有许多方法可提升网站的性能,有一些技巧可以避免踩坑。

    admin
  • 织梦CMS TAG页找不到标签和实现彩色标签解决方法

    织梦cms是我们常见的网站程序系统的一款,在TAG标签中常常遇到的问题也很多。当我们点击 tags.php 页的某个标签的时候,有时会提示:“系统无此标签,可 能已经移除!” 但是我们检查程序后台,以及前台显示页面。这个标签确实存在,如果解决这个问题那?

    admin
  • HTML关于fieldset标签主要的作用

    在前端开发html页面中常用的标签很多,今天为大家带来的是关于HTML中fieldset标签主要的作用说明,根据技术分析HTML

    admin

精选专题