当前位置: 首页 > news >正文

你会处理 go 中的 nil 吗

对于下面这段代码,我们知道 i 实际上的值就是 nil,所以 i == nil 会生效

func main() {var i *int = nilif i == nil {fmt.Println("i is nil") // i is nil}
}

现在换一种写法,我们将 i 的类型改成 interface{},i == nil 依然会生效

func main() {var i interface{} = nilif i == nil {fmt.Println("i is nil") // i is nil}
}

我们接着改造,将

 i == nil 的逻辑封装成函数 IsNil
go复制代码func IsNil(i interface{}) {if i == nil {fmt.Println("i is nil")}
}
func main() {var i *int = nilIsNil(i)
}

居然发现 IsNil 中的 i == nil 不生效了
这是为什么呢?
因为对于 interface{} 类型的值来说,如果要判断它是 nil,必须同时满足 type T 和 value V 都是 nil 才行
可以用 reflect 中的 TypeOf 和 ValueOf

var i *int = nil
fmt.Println(reflect.TypeOf(i), reflect.ValueOf(i)) // *int  <nil>var i interface{} = nil
fmt.Println(reflect.TypeOf(i), reflect.ValueOf(i)) // <nil> <invalid reflect.Value>

如果我们在函数中用 interface{} 作为参数的类型,表示并不代表参数就是 interface{} 类型,而是任意类型,调用时传入啥类型就是啥类型,如下代码

var i interface{} = 1
fmt.Println(reflect.TypeOf(i)) // intvar j interface{} = "hello"
fmt.Println(reflect.TypeOf(j)) // stringvar k interface{} = nil
fmt.Println(reflect.TypeOf(k)) // nil

所以只有当我们传入的参数类型是 interface{},且 value 为 nil 时,i == nil 才会生效
否则其他情况都不会生效

func main() {var i interface{} = nilIsNil(i)  // i is nil
}
func IsNil(i interface{}) {if i == nil {fmt.Println("i is nil")}
}

这个坑可能会出现在返回 error 的函数中,比如下面这段代码
在函数 SomeThing 中提前定义了 myError,然后一系列的处理后,返回了 myError
后面的业务逻辑需要判断 err 是否为 nil

type MyError struct{}
func (me *MyError) Error() string {return "my error"
}
func SomeThing() error {var myError *MyError    // 默认初始化为 nil// ...return myError
}
func main() {err := SomeThing()fmt.Println(reflect.TypeOf(err), reflect.ValueOf(err)) // *main.MyError <nil>if err != nil {     // 虽然没有返回,这里会被执行,因为 err 的类型不是 nilfmt.Println(err)}
}

从上面的代码我们看到,SomeThing 函数中定义的 myError 是 *MyError 类型,虽然返回了 nil,但是 err 的类型不是 nil,所以 err != nil 会生效,不符合预期
如果修改这个问题呢,当我们需要返回 nil 时,显示指明返回 nil,如下代码:

type MyError struct{}
func (me *MyError) Error() string {return "my error"
}
func SomeThing() error {var myError *MyError    // 默认初始化为 nil// ...return nil
}
func main() {err := SomeThing()fmt.Println(reflect.TypeOf(err), reflect.ValueOf(err)) // <nil> <invalid reflect.Value>if err != nil {     // 这段代码不会被执行fmt.Println(err)}
}

总结:需要返回 nil 时,要显示返回 nil,不要用指针类型的零值

相关文章:

你会处理 go 中的 nil 吗

对于下面这段代码&#xff0c;我们知道 i 实际上的值就是 nil&#xff0c;所以 i nil 会生效 func main() {var i *int nilif i nil {fmt.Println("i is nil") // i is nil} }现在换一种写法&#xff0c;我们将 i 的类型改成 interface{}&#xff0c;i nil 依然…...

高级深入--day42

注意&#xff1a;模拟登陆时&#xff0c;必须保证settings.py里的 COOKIES_ENABLED (Cookies中间件) 处于开启状态 COOKIES_ENABLED True 或 # COOKIES_ENABLED False 策略一&#xff1a;直接POST数据&#xff08;比如需要登陆的账户信息) 只要是需要提供post数据的&#xff…...

mysql 计算两个坐标距离

方式一&#xff1a;st_distance_sphere 计算结果单位米 SELECT *, st_distance_sphere(point(lng,lat),point(lng,lat)) as distance FROM table mysql 版本5.7 以上 方式二&#xff1a;st_distance 计算结果单位是度 SELECT *, (st_distance(point(lng,lat),point(lng4,lat…...

String、StringBuffer、StringBuilder和StringJoiner

String、StringBuffer、StringBuilder和StringJoiner都是用于处理字符串的类&#xff0c;但它们在性能和使用方式上有一些区别。 String String是不可变的类&#xff0c;一旦创建就不能被修改。对String进行拼接或修改时&#xff0c;实际上是创建了一个新的String对象。适用于…...

【数据结构】插入排序

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈数据结构 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 直接插入、希尔排序 1. 什么是排序2…...

Photoshop使用笔记总目录

Photoshop基础学习之工具学习 一、【Photoshop界面认识】 二、【 Photoshop常用快捷键】 三、【色彩模式与颜色填充】 四、【选区】 五、【视图】 六、【常用工具组】 七、【套索工具组】 八、【快速选择工具组】 九、【裁剪工具组】 十、【图框工具组】 十一、【吸取…...

最近面试遇到的高频面试题

大家好&#xff0c;我是 jonssonyan 互联网寒冬&#xff1f;金九银十真的不存在了么&#xff1f;虽说现在行情是差了一些&#xff0c;面试机会少了一些&#xff0c;但是大部分公司还是或多或少的招人&#xff0c;春招秋招都在进行。有人离职就有人入职。所以如果你还没约到面试…...

负载均衡有哪些算法,分别在nginx中如何配置?

负载均衡是用于分发传入的网络流量到多个后端服务器的技术&#xff0c;以确保无单个服务器过载&#xff0c;从而提高应用的可用性和响应时间。以下是一些常用的负载均衡算法&#xff0c;以及如何在Nginx中配置它们&#xff1a; 轮询 (Round Robin)&#xff1a; 简介&#xff1a…...

Starknet开发工具

1. 引言 目前Starknet的开发工具流可为&#xff1a; 1&#xff09;Starkli&#xff1a;音为Stark-lie&#xff0c;为替换官方starknet-CLI的快速命令行接口。Starkli为单独的接口&#xff0c;可独自应用&#xff0c;而不是其它工具的组件。若只是想与Starknet交互&#xff0…...

Unity地面交互效果——1、局部UV采样和混合轨迹

大家好&#xff0c;我是阿赵。   这期开始&#xff0c;打算介绍一下地面交互的一些做法。 比如&#xff1a; Unity引擎制作沙地实时凹陷网格的脚印效果 或者&#xff1a; Unity引擎制作雪地效果 这些效果的实现&#xff0c;需要基于一些基础的知识。所以这一篇先介绍一下简单…...

基于STM32的示波器信号发生器设计

**单片机设计介绍&#xff0c;基于STM32的示波器信号发生器设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序文档 六、 文章目录 一 概要 基于STM32的示波器信号发生器是一种高性能的电子仪器&#xff0c;用于测试和分析电路中的电信号。在该系统中&a…...

案例分析大汇总

案例分析心得 2018-2022年的案例分析考试内容汇总&#xff08;近五年&#xff09; 架构设计题型 软件系统建模 数据库 Web 系统设计 2018年 胖/瘦客户端 C/S 架构非功能性需求 数据流图DFDE-R图Essential Use Cases(抽象用例)&#xff0c;Real Use Cases(基础用例)信息工…...

MVCC(Multi-Version Concurrency Control,多版本并发控制)

是一种数据库管理系统中常用的并发控制技术&#xff0c;用于处理多个事务同时访问数据库数据时的数据一致性和隔离性。MVCC的主要目标是允许多个事务并发执行&#xff0c;同时保持数据的一致性&#xff0c;避免数据丢失或不一致。 MVCC 的核心思想是为每个事务维护多个版本的数…...

嵌入式面试2(c相关)

目录 1.C语言中static、const、volatile关键字用法区别&#xff1b; static的用法&#xff08;定义和用途) const的用法&#xff08;定义和用途&#xff09; volatile (英文意思为易变的) 作用和用法&#xff1a; 2.C语言中&#xff0c;const 和 static 的区别&#xff0c;c…...

基于SSM的n省出口基地公共信息服务平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

opencv dnn模块 示例(20) 目标检测 object_detection 之 yolor

文章目录 1、论文介绍1.1、YOLOR思想动机1.2、隐式知识学习1.2.1、隐式知识如何工作1.2.2、隐式知识统一网络建模 1.3、实验1.4、总结 2、测试2.1、opencv dnn2.1.1、代码2.1.2、结果 2.2、测试效率 YOLOR出自论文You Only Learn One Representation: Unified Network for Mult…...

【队列的顺序表示,链式表示】

文章目录 队列的表示和实现相关术语队列的表示链队的表示链队的定义链队的初始化销毁链队列 链队列的入队出栈 队列的表示和实现 相关术语 队列&#xff08;Queue&#xff09;是仅在表尾进行插入操作&#xff0c;在表头进行删除操作的线性表。表尾即an端&#xff0c;称为队尾…...

Pydantic 实践

1. 简介 pydantic 库是一种常用的用于数据接口 schema 定义与检查的库。 通过 pydantic 库&#xff0c;我们可以更为规范地定义和使用数据接口&#xff0c;这对于大型项目的开发将会更为友好。 当然&#xff0c;除了 pydantic 库之外&#xff0c;像是 valideer 库、marshmallo…...

获取pandas中的众数

pandas.DataFrame 也有一个 mode() 方法。 以下面的 pandas.DataFrame 为例。 df pd.DataFrame({‘col1’: [‘X’, ‘X’, ‘Y’, ‘X’], ‘col2’: [‘X’, ‘Y’, ‘Y’, ‘X’]}, index[‘row1’, ‘row2’, ‘row3’, ‘row4’]) print(df) col1 col2 row1 X X row2…...

SOLIDWORKS Simulation2024仿真10大新功能

SOLIDWORKS Simulation新增功能 1. 增强型轴承接头 •通过指定压缩、拉伸和弯曲的刚度&#xff0c;轻松创建自定义轴承接头。•通过向非线性和大型位移算例添加自定义条件&#xff0c;提高模拟精度。 优点&#xff1a;使用功能强大的接口&#xff0c;更轻松 、 更 准 确 地 设…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

虚幻基础:角色旋转

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 移动组件使用控制器所需旋转&#xff1a;组件 使用 控制器旋转将旋转朝向运动&#xff1a;组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转&#xff1a;必须移动才能旋转&#xff0c;不移动不旋转控制器…...

HTML中各种标签的作用

一、HTML文件主要标签结构及说明 1. <&#xff01;DOCTYPE html> 作用&#xff1a;声明文档类型&#xff0c;告知浏览器这是 HTML5 文档。 必须&#xff1a;是。 2. <html lang“zh”>. </html> 作用&#xff1a;包裹整个网页内容&#xff0c;lang"z…...