Golang-如何判断一个 interface{} 的值是否为 nil ?

news2024/11/16 9:39:37

引用

起初我会下意识的回答,直接 v == nil 进行判断不就好了吗?
然后翻阅了很多资料终于大致搞定里面的道道.

例子

请看下面这段代码,可以先猜测一下输出的结果。

package main

import (
    "fmt"
)

func main()  {
    var a *string = nil
    var b interface{} = a

    fmt.Println(b==nil) 
}

答案应该会跟你下意识的回答 相反

输出的结果的是 false

两个 interface 比较

interface 的内部实现包含了两个字段,一个是 type,一个是 data

对于这样一个变量
var age interface{} = 25

其实内部结构是
在这里插入图片描述
因此两个 interface 比较,势必与这两个字段有所关系。

经过验证,只有下面两种情况,两个 interface 才会相等。

第一种情况

typedata 都相等

看以下代码例子:

package main

import "fmt"

type Profile struct {
    Name string
}

type ProfileInt interface {}

func main()  {
    var p1, p2 ProfileInt = Profile{"iswbm"}, Profile{"iswbm"}
    var p3, p4 ProfileInt = &Profile{"iswbm"}, &Profile{"iswbm"}

    fmt.Printf("p1 --> type: %T, data: %v \n", p1, p1)
    fmt.Printf("p2 --> type: %T, data: %v \n", p2, p2)
    fmt.Println(p1 == p2)  // true

    fmt.Printf("p3 --> type: %T, data: %p \n", p3, p3)
    fmt.Printf("p4 --> type: %T, data: %p \n", p4, p4)
    fmt.Println(p3 == p4)  // false
}

运行后,输出如下

p1 --> type: main.Profile, data: {iswbm} 
p2 --> type: main.Profile, data: {iswbm} 
true
p3 --> type: *main.Profile, data: 0xc00008e200 
p4 --> type: *main.Profile, data: 0xc00008e210 
false
  • 在代码中,p1p2type 都是 Profiledata 都是 {"iswbm"},因此 p1p2 相等
  • p3p4 虽然类型都是 *Profile,但由于 data 存储的是结构体的地址,而两个地址和不相同,因此 p3 p4 不相等

第二种情况

特殊情况:两个 interface 都是 nil

当一个 interface 的 type 和 data 都处于 unset 状态的时候,那么该 interface 的类型和值都为 nil

package main

import "fmt"

func main() {
    var p1, p2 interface{}
    fmt.Println(p1 == p2)  // true
    fmt.Println(p1 == nil) // true
}

interface 与 非 interface 比较

当 interface 与非 interface 比较时,会将 非interface 转换成 interface ,然后再按照 两个 interface 比较 的规则进行比较。

示例代码:

package main

import (
    "fmt"
    "reflect"
)

func main()  {
    var a string = "iswbm"
    var b interface{} = "iswbm"
    fmt.Println(a==b) // true
}

上面这种例子可能还好理解, atype string, valueiswbm , btype string, valueiswbm ,所以打印为true

那么请你看下面这个例子(文章开头的示例),为什么 b 与 nil 不相等?

package main

import (
    "fmt"
)

func main()  {
    var a *string = nil
    var b interface{} = a

    fmt.Println(b==nil) // false
}

但当你使用 b==nil 进行判断时,其实右边的 nil 并非单纯的是我们所理解的值为nil,而正确的理解应该是 type 为 nil 且 value 也为 nil。

Go 会先将 nil 转换为interface (type=nil, data=nil) ,这与 b (type=*string, data=nil) 虽然 data 是一样的,但 type 不相等,因此他们并不相等

那有没有办法判断一个 interface{} 是不是 nil 呢?

有办法的,但是要借助反射,一个非万不得已不会使用的 reflect 包。

package main

import (
    "fmt"
    "reflect"
)

func IsNil(i interface{}) bool {
    vi := reflect.ValueOf(i)
    if vi.Kind() == reflect.Ptr {
        return vi.IsNil()
    }
    return false
}

func main() {
    var a *string = nil
    var b interface{} = a
    fmt.Println(IsNil(b))
}

参考

如何判断一个 interface{} 的值是否为 nil ?
彻底理解golang中什么是nil

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/509879.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网安笔记 08 key management

Key Management —— 不考 网络加密方法 1.1 链路加密 特点: 两个相邻点之间数据进行加密保护 不同节点对密码机和Key不一定同中间节点上,先解密后加密报文报头可一起加密节点内部,消息以明文存在密钥分配困难保密及需求数量大 缺点&…

day36_jdbc

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、JDBC 二、登录 三、ORM 零、 复习昨日 sql语言:DDL DML DQL DCL create table 表名(id int primary key auto_increment,sname varchar(2…

【SAP Abap】X-DOC:SMW0 - Excel 导入模板的上传和下载

X-DOC:SMW0 - Excel 导入模板的上传和下载 1、实现效果2、模板上传3、下载功能代码 做批导程序,离不开 Excel 导入模板,为了方便用户,一般会将模板文档整合到导入功能的界面上,方便用户获取模板。 1、实现效果 2、模板…

两个form表单的数据存入同一个数据库表,使用使用json操作

项目场景: 两个form表单的数据存入同一个数据库表 问题描述 1.两个from表单数据一起传到后端但是数据解析和xml文件的sql获取不到报错 2.数据接受到了但是提示数据类型不兼容 3.使用RequestBody注解报错Content type application/x-www-form-urlencoded;charsetUT…

深入解析linux IO Block layer

早期的 Block 框架是单队列(single-queue)架构,适用于“硬件单队列”的存储设备(比如机械磁盘),随着存储器件技术的发展,支持“硬件多队列”的存储器件越来越常见(比如 NVMe SSD&…

makefile 变量的替换,嵌套引用,命令行变量

文章目录 前言一、变量替换:1. 变量值的替换。2. 变量的模式替换。3. 规则中的模式替换。 二、变量的嵌套使用三、命令行变量四、override ,define 关键字总结 前言 一、变量替换: 1. 变量值的替换。 使用 指定的字符(串)替换变…

ctfshow web入门 ssrf web351-355

1.web351 尝试访问本机的flag.php payload: urlhttp://localhost/flag.php urlhttp://127.0.0.1/flag.php2.web352 必须要用http或https,ip没有过滤因为匹配时没加变量,恒为真 payload: urlhttp://127.0.0.1/flag.php urlhttp://localhost/flag.php3.…

智能美妆镜兴起,如何升级更精细、智能的化妆体验!

经常化妆的小姐姐,会发现化妆除了要有好皮肤、一堆化妆品之外,化妆镜的作用也尤其重要!爱拍照的小姐姐们都知道,自拍的效果好不好,和背景、灯光有着很大的关系,其中灯光的冷调或者暖调,也是影响…

Linux网络——Shell编程之数组

Linux网络——Shell编程之数组 一、概念二、数组的定义三、Shell数组操作1. 获取数组的所有元素的列表2. 获取数组的所有元素下标3.取数组的元素个数4. 获取数组的某个元素的值5.删除数组某个元素6.删除数组7.数组切片8.数组字符替换9.数组追加元素 四、数组在函数的传参 一、概…

阿里云Intel(R) Xeon(R) Platinum处理器2.5 GHz主频

阿里云服务器CPU处理器Intel(R) Xeon(R) Platinum,2.5 GHz主频,3.2 GHz睿频,测试的云服务器ECS为通用算力型u1实例ecs.u1-c1m2.large,如下图: 阿里云服务器CPU处理器Intel(R) Xeon(R) Platinum 目前使用这款CPU处理器…

c++类和对象重要巩固练习-------日期类对象

这是对于类和对象的练习篇&#xff0c;用c来模拟完成日期计算器。 这其中需要我们完成&#xff1a; 日期 - 天数后 得到的新日期 日期 - 日期 得到相差的天数比较日期的大小等 .....具体如下头文件类中的成员函数 #pragma once #include<iostream> using namespace std…

【UE】简单实现屏幕UI定位

【UE】简单实现屏幕UI定位三维坐标方法 实现效果 屏幕空间定位 场景空间定位 一般实现兴趣点&#xff08;POI&#xff09;有两种实现方法&#xff0c;场景空间UI定位和屏幕空间UI定位。 场景空间定位&#xff1a;UI类似实例模型&#xff0c;位置和尺寸是相对于场景不变。大多…

Laravel 知识整合 1 路由

Laravel是一种基于php的MVC web开发框架 php artisan make:controller NAME//创建一个名字为name的controller路由&#xff1a;routes/web.php Route::get(/students,StudentControllerindex); 控制器&#xff1a;app/HTTP/Controllers&#xff08;可以直接用命令行生成&…

SSM框架学习-依赖注入、自动装配、暴力反射

1. 依赖注入 1.1 引用类型 注入引用类型 一种是默认按照类型装配 一种是如果有相同类型的bean采用按bean名称装配 但是在写的过程中Qualifier前面必须写上Autowired 也就是必须依赖Autowired //Autowired&#xff1a;注入引用类型&#xff0c;自动装配模式&#xff0c;默认按类…

一场面试下来,狂飙 Framework底层原理

近期有位Android 开发的朋友在吐槽说&#xff1a;现在的招聘信息网站是假的吧&#xff0c;我都怀疑一些公司的人事在冲他们的KPI&#xff0c;三个月了&#xff0c;简历投了上百份&#xff0c;结果收到回应的才个位数&#xff0c;去面试还一套Framework底层原理面试题狂炸…… 面…

178_技巧_Power BI 动态排名多项展示

178_技巧_Power BI 动态排名多项展示 一、背景 在 Power BI 中做排名矩阵时&#xff0c;我们经常遇到同一维度下&#xff0c;多项展示排名的问题。类似这样的排名矩阵&#xff0c;排名的名次不会太多&#xff0c;但是同一维度下会有多项同时展示排名&#xff0c;并且还要满足…

树结构 数据可视化

这边有个 树结构数据&#xff0c;想做一个可视化展示的需求&#xff1b;首先想到的是 python pyecharts, 一直传说 python 做数据可视化 一把梭&#xff1b; pyecharts 在线实例展示 pyecharts 官网 当看到上面的 示例 后&#xff0c;这不就我想找的嘛&#xff01;哈哈 随后 找…

web前端 --- CSS(02) -- 样式修饰

CSS本质是用来修饰HTML标签的 常用CSS属性 &#xff08;1&#xff09;字体及文本属性 文字相关效果 属性含义font字体及其属性&#xff08;复合属性&#xff0c;不建议直接使用&#xff09;font-family设置文本字体&#xff0c;电脑中存在字体font-size字体大小font-weight字…

PPT如何使用基础功能?

文章目录 0.引言1.菜单栏 0.引言 因科研办公等多场景需要进行汇报展示&#xff0c;笔者对PPT进行了学习&#xff0c;通过《PPT 2016高效办公实战应用与技巧大全666招》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;本文对软件界面基础功能进行阐述。    1.菜单…

[光源频闪] Basler相机光源频闪设置操作说明

&#x1f4e2;博客主页&#xff1a;https://loewen.blog.csdn.net&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由 丶布布原创&#xff0c;首发于 CSDN&#xff0c;转载注明出处&#x1f649;&#x1f4e2;现…