【Go 语言社区】Golang中interface判断nil问题
时间:2022-05-04
本文章向大家介绍【Go 语言社区】Golang中interface判断nil问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
在示例中,我们定义一个interface名为Stringer,同时定义一个符合其定义的Binary类型:
type Stringer interface {
String() string
}
type Binary uint64
func (i Binary) String() string {
return strconv.Uitob64(i.Get(), 2)
}
func (i Binary) Get() uint64 {
return uint64(i)
}
func ToString(any interface{}) string {
if v, ok := any.(Stringer); ok {
return v.String()
}
switch v := any.(type) {
case int:
return strconv.Itoa(v)
case float:
return strconv.Ftoa(v, 'g', -1)
}
return "???"
}
复制代码
如果将一个Binary类型的变量b b=Binary(200)赋值给一个interface类型的值,排除内存优化的因素,将会形成以下的结构:
可以看到,interface变量由代表类型的itable和代表值的data来表示<itable, data>。 itable中保留的仅有Stringer类型包含的方法,其余Binary的方法并不在interface变量中可见。 data变量保存的是原数据b的一份拷贝,而不是简单的引用。
Golang中的nil:
由定义可知:
- var nil Type // Type must be a pointer, channel, func, interface, map, or slice type
复制代码
nil is a predeclared identifier representing the zero value for a pointer, channel, func, interface, map, or slice type.
判断interface为nil:
只有当interface为零值,即<itable, data>=<nil, nil>时,才能等于nil。
在上面的例中,如有有这样一个方法:
func isNil(s Stringer) {
defer func() {
if e := recover(); e != nil {
fmt.Printf("panic in isNil(), err:%vn", e)
}
}()
if s == nil {
fmt.Printf("judge1:s(%v) == niln", s)
return
}
if reflect.ValueOf(s).IsNil() {
fmt.Printf("judge2:s(%v) reflect niln", s)
return
}
fmt.Printf("s(%v) passn", s)
}
- isNil(nil)将会输出judge1 输入的nil将会被赋值成<nil, nil>的interface,可以用==nil来判断
- var b *Binary; isNil(b)将会输出judge2 输入的b被赋值成<type=*Binary, value=nil>类型的interface(*Binary和Binary都能满足Stringer接口定义),不能==nil,而reflect.ValueOf(s)返回了具体类型的reflect.Value表示,此处即为*Binary的reflect.Value表示,isNil接受interface类型判断为nil
- var b Binary; isNil(b)将会输出panix in isNil() 输入的b被赋值成<type=Binary, value=Binary(0)类型的interface,而reflect.ValueOf(s)返回了具体类型的reflect.Value表示,此处即为Binary(0)的reflect.Value表示,而reflect.Value.isNil只接受“ a chan, func, interface, map, pointer, or slice value”,故panic
- mysql主从同步(4)-Slave延迟状态监控
- 浏览器窗口尺寸改变时的图片自动重新定位
- Mongodb主从复制/ 副本集/分片集群介绍
- Paul-Adrien Menez:互联网与抵制食物浪费的故事
- DRBD详细解说及配置过程记录
- Servant:基于Web的IIS管理工具
- Web前端知识体系精简——CSS 篇
- 几种异步操作方式
- 今天的面试小记
- objective-C中的序列化(serialize)与反序列化(deserialize)
- 微信小程序 template 模板功能实现循环
- ASP.NET Web API 接口执行时间监控
- 这么多前端优化点你都记得住吗?
- 愚蠢的”记住“密码方式终于还是出了问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android 天气APP(二十六)增加自动更新(检查版本、通知栏下载、自动安装)
- Android 天气APP(二十七)增加地图天气的逐小时天气、太阳和月亮数据
- Android 天气APP(二十八)地图搜索定位
- DevEco Studio项目构建讲解、编写页面、布局介绍、页面跳转
- Android 天气APP(二十九)壁纸设置、图片查看、图片保存
- Chrome 私人珍藏-stylus插件实现个性化百度界面定制
- Python 基础篇-简单的异常捕获
- Python 技巧篇-让我的程序暂停一下
- Python+selenium 技术篇-浏览器后台运行
- Python 基础篇-python3安装pyHook和pywin32库
- 漫画:如何螺旋遍历二维数组?(修订版)
- 一文快速入门分库分表(必修课)
- 写出漂亮 Python 代码的 20条准则
- 简单red5+obs推流实现直播系统开发,具体设置介绍
- 使用pandas进行数据快捷加载