这些关于Go中interface{}的注意事项你都了解吗
作者:阿兵云原生 发布时间:2024-02-01 08:20:19
我们一起来回顾一下上一次说到的 interface{}
可以用来做多态
接口类型分为空接口类型和非空接口类型,他们的底层数据结构不太一样
这里顺便说一下,用来作态需要满足这样的条件:
首先得有父类指针指向子类的对象
这个接口还必须是非空接口,里面得包含方法,也就是使用的底层数据结构是 iface
子类会去实现父类的具体方法
interface{} 注意断言
正常的使用断言,写一个简单的 断言 demo
type Animal interface{}
func main() {
var a Animal = "xiaomotong"
v, ok := a.(string)
if !ok{
fmt.Println("type error")
}
fmt.Println("v == ",v)
}
断言注意写成 2 个返回值的,一个是具体的值,一个是 bool,判断断言是否成功,若成功则说明断言正确,且 v 会被赋值为实际变量的值
切忌没头脑的强转
func main() {
var a Animal = "xiaomotong"
v := a.(int)
fmt.Println("v == ",v)
}
上述这种写法,若不判断是否断言成功,直接强转,程序是会 panic 的 ,执行上述程序后效果如下:
>go run main.go
panic: interface conversion: main.Animal is string, not int
goroutine 1 [running]:
main.main()
D:/mycode/my_new_first/interface_test/main.go:13 +0x4c
exit status 2
程序崩掉,那就是线上问题了 xdm ,这里需要注意
当然我们也可以这样写
type Animal interface{}
func main() {
var a Animal = "xiaomotong"
switch a.(type) {
case string:
fmt.Println("a type is string")
case int:
fmt.Println("a type is int")
}
}
通过 switch 的方式来判断 接口的数据类型,根据不同的数据类型来做不同的事情,进行分类处理
用于反射的注意点
golang 里面有反射这个概念,简单来说,咱们可以通过反射包来实现获取接口真实的类型,和真实的数据
举个小例子:
通过反射来获取 Animal 接口的数据类型,和具体的数据值
type Animal interface{}
func main() {
var a Animal = "xiaomotong"
v := reflect.ValueOf(a)
fmt.Printf("v type == ", v.Type(), " v == ", v.String())
}
执行上述代码后效果如下:
> go run main.go
v type == %!(EXTRA *reflect.rtype=string, string= v == , string=xiaomotong)
没毛病正常获取,但是如果我们这样写的话是不是也可以正确执行呢?
type Animal interface{}
func main() {
var a Animal = "xiaomotong"
v := reflect.ValueOf(a)
fmt.Printf("v type == ", v.Type(), " v == ", v.Int())
}
看这个例子也就和上面的例子相差在输出的时候,一个是v.String()
,一个是v.Int()
,可是结果却相差很大
go run main.go
v type == %!(EXTRA *reflect.rtype=string, string= v == , string=xiaomotong)
D:\mycode\my_new_first\interface_test>go run main.go
panic: reflect: call of reflect.Value.Int on string Value
goroutine 1 [running]:
reflect.Value.Int(...)
C:/Program Files/Go/src/reflect/value.go:999
main.main()
D:/mycode/my_new_first/interface_test/main.go:26 +0x2bd
exit status 2
执行上述代码,go 程序给我们报了 panic 错误,这里需要注意 ,程序崩溃的原因是,我们将一个 string 类型的值反射成一个 Int 类型的值,直接在 反射包里面就给我们报了 panic
来源:https://segmentfault.com/a/1190000043511770


猜你喜欢
- 我们在编写asp程序时经常会使用到这个功能,一般我们这样判断如:if a="" then ,而这个函数考虑的就比较全面了
- 下列语句部分是Mssql语句,不可以在access中使用。 SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECL
- JavaScript 中的并没有提供像 VBScript 里的 DateAdd 方法用于日
- 对图片进行resize、裁剪、旋转、翻转图片处理时常用的手段有resize、裁剪、旋转、翻转,简单介绍一下python中怎么利用PIL库和t
- 利用networkx,numpy,matplotlib,将邻接矩阵输出为图形。1,自身确定一个邻接矩阵,然后通过循环的方式添加变,然后输出图
- python控制鼠标键盘其实很容易,我们在写程序的时候很多时候会用的到!python控制鼠标键盘步骤及代码1、安装类库pip install
- 前几天安装Python的时候没有装上pip工具,所以只能现在手动安装了。首先,访问https://bootstrap.pypa.io/get
- 一、背景今天有个小需求,要确认客户端有没有往服务端发送udp包,但为了减轻工作量,不想每次到机器上手动执行tcpdump抓包命令。于是就写了
- 方式1:在pygame中使用pygame.event.get()方法捕获键盘事件,使用这个方式捕获的键盘事件必须要是按下再弹起才算一次。示例
- 在图片处理过程中,有时候我们想要确定图片中某一像素的坐标,可以通过下面方法得到。点击运行程序,用鼠标点击我们想要获取坐标的区域,即可获得其坐
- CSS3草案中定义了{opacity:来声明元素的透明度,这已经得到了大多数现代浏览器的支持,而IE则很早通过特定的私有属性filter来实
- 通常,你需要获得当前日期和计算一些其他的日期,例如,你的程序可能需要判断一个月的第一天或者最后一天。你们大部分人大概都知道怎样把日期进行分割
- 如下所示:import pandas as pd #显示所有列pd.set_option('display.max_columns&
- 效果图实现代码vue2 代码如下<!-- 横向柱状图测试结果 --><template> <div
- 闲暇时间用tkinter写了个简易计算器,可实现简单的加减乘除运算,用了Button和Entry2个控件,下面是代码,只是简单的用了偏函数p
- 1.必需的参数:必须参数须以正确的顺序传入函数,调用的数量必须和声明时的一样def f(name,age):print('I am
- 本文实例为大家分享了JavaScript缓动动画函数的封装代码,供大家参考,具体内容如下本文将从封装缓动动画的以下几个部分进行封装(1、单个
- 导语嘿!下午好,木子来上新啦~期待今天的内容嘛?挠头.jpg 日常等更新的小可爱们我来了。看看给大家带来了什么好东西💦💦💦💦💦💦💦💦💦💦💦💦
- 使用TensorFlow模块时,弹出错误Your CPU supports instructions that this TensorFlo
- 什么是插槽?我们知道在Vue中 Child 组件的标签 的中间是不可以包着什么的 。可是往往在很多时候我们在使用组件的时候总想在组件间外面自