27. 说说 Go 语言中的类型断言?(27.5英寸是多少厘米)

网友投稿 901 2022-09-18

27. 说说 Go 语言中的类型断言?(27.5英寸是多少厘米)

27. 说说 Go 语言中的类型断言?(27.5英寸是多少厘米)

1. Type Assertion

Type Assertion(中文名叫:类型断言),通过它可以做到以下几件事情

检查 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=====

 - false

=====分隔线3=====

10-true

10-true

上面这段输出,仔细看第二个断言的输出在-false  之前并不是有没有输出任何 t2 的值,而是由于断言失败,所以 t2 得到的是 string 的零值也是 "" ,它是零长度的,所以你看不到其输出。

2. 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

 is nil

10.23 not type matched

额外说明一下:

如果你的值是 nil,那么匹配的是 case nil

如果你的值在 switch-case 里并没有匹配对应的类型,那么走的是 default 分支

留言纠错

由于这个号,没有留言功能,文章中不可避免(尽管我已经尽力验证充分)会出现一些小毛病。

为了避免文章因我个人语言表达不当,或者个人理解有误,而误导初学者,请大家共同监督,若文章有说的不对的地方,请在下方链接里留言,帮我指正。谢谢大家,共同努力。Fighting

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:改错:[WinError 10061] 由于目标计算机积极拒绝,无法连接。解决办法
下一篇:Windows上实现iOS APP自动化测试:tidevice + WDA + airtest
相关文章

 发表评论

暂时没有评论,来抢沙发吧~