• 技术文章 >后端开发 >Golang

    go语言类型断言是啥

    青灯夜游青灯夜游2023-01-12 10:57:31原创100

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

    本教程操作环境:windows7系统、GO 1.18版本、Dell G3电脑。

    断言是什么?

    断言是编程术语,表示为一些布尔表达。编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设。简单的来理解断言的话就是判断的意思。所以在Go中类型断言我们就可以理解成对类型的判断。

    类型断言介绍

    类型断言(Type Assertion)是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型。

    在Go语言中类型断言的语法格式如下:

    value, ok := x.(T)

    其中,x 表示一个接口的类型,T 表示一个具体的类型(也可为接口类型)。

    该断言表达式会返回 x 的值(也就是 value)和一个布尔值(也就是 ok),可根据该布尔值判断 x 是否为 T 类型:

    在Go中类型断言主要有两种形式

    类型断言的用法

    通过类型断言可以做到以下几件事情

    具体的使用方式有两种:

    第一种:

    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视频教程编程教学

    以上就是go语言类型断言是啥的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:go语言中变量声明方法有哪些 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • go语言接口类型怎么转换• Go语言中goroutine是啥• Go语言GOPATH是什么• go语言中for range是什么结构• Go语言中延迟执行语句是什么• Go语言的词法元素有几类
    1/1

    PHP中文网