首页 > 其他分享 >(转)Go 语言中的类型断言是什么?

(转)Go 语言中的类型断言是什么?

时间:2023-04-03 23:22:13浏览次数:44  
标签:ok 断言 nil fmt interface Go main 语言

原文:https://juejin.cn/post/6844904153056034823

Type Assertion

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

  1. 检查 i 是否为 nil
  2. 检查 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 分支

参考文章

标签:ok,断言,nil,fmt,interface,Go,main,语言
From: https://www.cnblogs.com/liujiacai/p/17284891.html

相关文章

  • Webgoat学习笔记
    Webgoat学习笔记Webgoat分为简单版和开发版,具体版本及安装方法详见:https://github.com/WebGoat/WebGoat本机环境为:Windows+Tomcat,故下载war包,自动解压缩进行部署。war下载地址:https://github.com/WebGoat/WebGoat/releases/    参考链接:Webgoat学习笔记:http://www.tui......
  • Django笔记十五之in查询及date日期相关过滤操作
    这一篇介绍关于范围,日期的筛选inrangedateyearweekweekdayquarterhour1、inin对应于MySQL中的in操作,可以接受数组、元组等类型数据作为参数:Blog.objects.filter(id__in=[1,2,3])对应的SQL是:select*fromblog_blogwhereidin(1,2,3);字符串也可以作......
  • 【数据结构】二叉树先序、中序、后序及层次遍历(C语言版)
    一、图示展示1.先序遍历先序遍历可以想象为,一个小人从一棵二叉树根节点为起点,沿着二叉树外沿,逆时针走一圈回到根节点,路上遇到的元素顺序,就是先序遍历的结果先序遍历结果为:ABDHIEJCFKG动画演示:记住小人沿着外围跑一圈(直到跑回根节点),多看几次动图便能理解2.......
  • Goop:滚吧,小怪兽
    别误解标题的意思,Goop是并不是要玩家扮演打小怪兽的奥特曼,而是要帮助一只只小怪兽躲过变成落汤鸡的危险,而怎么帮助他们呢,让他们滚着躲过水滴就好了。游戏名称:Goop游戏平台:iOS游戏价格:限时免费,原价0.99美金(6元人民币)评分:画面/音效:6/10游戏操作:8/10游戏......
  • C语言再学习 -- 详解C++/C 面试题 2
    (经典)C语言测试:想成为嵌入式程序员应知道的0x10个基本问题。参看:嵌入式程序员面试问题集锦1、用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #defineSENCONDS_PER_YEAR(60*60*24*365)UL解答:#define声明一个常量,使用计算常量表达式的值来表明一年中有多少......
  • 第一篇 go之基本类型与函数使用
    go之基本类型与函数使用目录go之基本类型与函数使用一、go语言介绍1go语言介绍2go语言特性3go的历史发展4go语言的应用领域二、go语言开发环境1go环境配置2go常用命令三、第一个helloworld四变量1变量定义2变量定义规范2.1变量命名规范2.2go语言中的关键字五数据类......
  • C语言再学习 -- 输入/输出
    一、缓冲区输入字符的立即回显是非缓冲或直接输入的一个实例,它表示你说键入的字符被收集并存储在一个被成为缓冲区的临时存储区域中。按下回车可使你所键入的字符块对程序变成可用。为什么需要缓冲区?首先,将若干个字符作为一个块传输比逐个发送这些字符耗费的时间少。其次,如果你输入......
  • C语言再学习 -- 运算符与表达式
    分三部分来讲一、左值与右值参看:左值与右值首先我们需要理解左值和右值的定义:左值指的是如果一个表达式可以引用到某一个对象,并且这个对象是一块内存空间且可以被检查和存储,那么这个表达式就可以做为一个左值。      右值指的是引用了一个存储在某个内存地址里的数据。从上面......
  • Golang基本语法笔记
    数据类型整型取值范围varnint8n=100fmt.Println(n)//100没有问题//如果赋值为200则不行因为int8取值范围最大是127字符串 v1:='A'v2:="A" //单引号存储的是ASCII编码//A的ASCII值=65//B的ASCII值B=66//a的ASCII值a=97 fmt.Printf("v1的类型是%T,%d,值为%s\n"......
  • Golang环境安装
    Go语言简介什么是Go语言Go语言是谷歌2009发布的第二款开源编程语言。Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。Go语言具有很强的表达能力,它简洁、清晰而高效。得益于其并发机制,用......