golang踩坑 3.接口值是否等于nil

Golang中error的一个坑 err != nil 第一个问题是:为什么值为 nil 的 error 却不等于 nil? 思考如下代码: package main import ( "errors" "fmt" ) type Err struct { err string } func (e *Err) Error() string { return e.err } func ... 阅读详情

就像雨总会停,雾总会散,同样地没有谁会一直失败。

详细请点击微信公众号:golang踩坑 3.接口值是否等于nil

1. 前言

这篇文章我们就来聊聊接口值等于nil这种常见类型零值的判断,有些童鞋在用的过程中难免会犯错,犯错之后又不知如何改正,那么接下来我就给大家把这个坑填上。

2. 接口值是否等于nil

具体类型的nil值, 赋值给接口值变量后, 被判定不为nil。

func main() {

    // *bytes.Buffer, 零值为nil
    var b *bytes.Buffer

    if b == nil {
        fmt.Println("外面的b等于nil")
    } else {
        fmt.Println("外面的b不等于nil")
    }

    f := func(b io.Writer) {
        if b == nil {
            fmt.Println("里面的b等于nil")
        } else {
            fmt.Println("里面的b不等于nil")
        }
    }

    // 把b传入函数
    f(b)

}

//===========输出===============

外面的b等于nil
里面的b不等于nil

原因:

golang中的接口值, 除了有自己的类型type外, 还有动态类型(dynamic type)和动态值(dynamic value). 接口值如果要被判断为nil, 需要动态类型和动态值都为nil. 可以通过fmt的"%T", “%v"观察动态类型和动态值。

3. 打印动态类型和动态值

func main() {

    var b *bytes.Buffer

    fmt.Printf("外面的b类型为%T\n", b)
    fmt.Printf("外面的b值为%v\n", b)

    if b == nil {
        fmt.Println("外面的b等于nil")
    } else {
        fmt.Println("外面的b不等于nil")
    }

    fmt.Println("")

    f := func(b io.Writer) {
        fmt.Printf("里面的b类型为%T\n", b)
        fmt.Printf("里面的b值为%v\n", b)
        if b == nil {
            fmt.Println("里面的b等于nil")
        } else {
            fmt.Println("里面的b不等于nil")
        }
    }

    f(b)

}

//==============输出=================

外面的b类型为*bytes.Buffer
外面的b值为<nil>
外面的b等于nil

里面的b类型为*bytes.Buffer
里面的b值为<nil>
里面的b不等于nil

4. 小结

我们看到当把一个具体类型赋值给接口之后,这个接口一定不是nil,因为接口的动态类型保存着具体类型的type,但是接口的动态值可能是nil,所以只要有一个不为nil,那么接口就不是nil,这个大家要在以后的代码中谨慎一些。具体大家可以看下interface的源码实现就知道为什么了。

5. 关注公众号

微信公众号:堆栈future

希望大家关注哈,原创不容易,求点赞,求关注,求分享

扫码_搜索联合传播样式-标准色版.png

go interface{}==nil 几种坑及原理 本文是Go比较有名的一个坑,在以前面试的时候也被问过,为什么想起来写这个? 因为我们线上就真实出现过这个坑,写给不了解的人在使用 if err != nil 的时候提高警惕。 Go语言的interface{}在使用过程中有一个特别坑的特性,当你比较一个interface{}类型的值是否是nil的时候,这是需要特别注意避免的问题。 先来看看一个demo: package main import "... 阅读详情

相关推荐

从编译到调通:RK3588与FPGA的PCIe XDMA驱动实战解析

本文详细解析了在RK3588平台上为FPGA板卡编译、加载与调试PCIe XDMA驱动的完整实战流程。内容涵盖环境准备、Makefile深度定制、编译排错、驱动加载与内核日志解读、设备节点分析以及用户空间编程实战,旨在帮助开发者打通RK3588与FPGA之间的高速PCIe通信链路,实现稳定可靠的数据传输。

weixin_29304021的博客 482

Golang 指针nil问题、结构体判空 踩坑-1

背景 1 有两个方法A 、B 以及一个结构体 P , AB中传递的是P的指针 问题1 代码如下 此代码看着没有明显报错,当你编译的时候不会报错,能打包,但是你运行的时候会报错, panic: runtime error: invalid memory address or nil pointer dereference , 提示是个空指针。 分析 为什么会这样呢,我们首先是初始化了一个结构体指针p,此时它的值是nil,但是我们并没有进行数据存储操作,所以p的指向不变,仍然是ni...

PHPerJiang 8544

鸿蒙之HML语法参考

HML(HarmonyOS Markup Language)是一套类HTML的标记语言,通过组件,事件构建出页面的内容。页面具备数据绑定、事件绑定、条件渲染和逻辑控制等高级能力。

2401_82772199的博客 1649

Go工程大坑,空切片和nil切片

nil是为pointer、channel、func、interface、map或slice类型预定义的标识符,代表这些类型的零值。可见,在Go中,nil代表的是上述类型的零值。切片类型的默认零值是nil,所以在上述的代码中s是nil切片。同时s的长度是0,可见nil切片也是空切片。既然都是空切片,那么nil切片和非nil的空切片的区别是什么呢?我们知道,slice的底层结构体中是由3个字段构成的:长度,容量和指向底层数组的指针字段。如下图:而nil切片除了长度和容量都是0之外,还有就是。

qq_61039408的博客 1836

【开关电源】开关电源实战经验分享

开关电源原理设计、Layout设计经验分享

weixin_42098658的博客 4168

Matlab TreeBagger实战:用随机森林预测房价的5个关键步骤(附完整代码)

本文详细介绍了使用Matlab的TreeBagger工具包构建随机森林模型预测房价的完整流程。通过波士顿房价数据集实战,涵盖数据预处理、模型构建、参数调优、特征重要性分析及高级应用(如分位数回归)等5个关键步骤,并附有完整代码,帮助读者快速掌握这一强大的回归分析工具。

ol789012的博客 444

Golang可能会踩的58个坑(转载)

Go 是一门简单有趣的编程语言,与其他语言一样,在使用时不免会遇到很多坑,不过它们大多不是 Go 本身的设计缺陷。如果你刚从其他语言转到 Go,那这篇文章里的坑多半会踩到。

钟长森的博客 4100

阿里云大模型ACP认证模拟考试(一)

摘要:在阿里云大模型高级工程师 ACP 认证暂无真题题库的现状下,模拟题具有重要意义。其依照真实考试设计,涵盖题型、题量与分值分布,助力考生熟悉考试框架,合理分配答题时间精力,提升效率。同时,模拟题紧扣官方课程,能帮助考生精准定位知识盲点,如大模型架构原理和通义千问应用实践等重点内容,以便针对性完善知识体系。此外,通过练习模拟题,考生可掌握不同题型的解题思维与技巧,快速洞察复杂题目本质,提高答题准确率。

davidkorhenn的博客 4737

golang:接口的nil判断

下面代码使用 MyImplement() 实现 fmt 包中的 Stringer 接口,这个接口的定义如下: type Stringer interface { String() string } 在 GetStringer() 函数中将返回这个接口。通过 *MyImplement 指针变量置为 nil 提供 GetStringer 的返回值。在 main() 中,判断 GetStringer 与 nil 是否相等,代码如下: package main import "fmt" // 定义一个结构

OceanStar的博客 857

三相逆变器LCL滤波设计实战:从αβ转换到dq解耦控制的完整建模流程

本文详细解析了三相逆变器LCL滤波设计中的关键步骤,从αβ转换到dq解耦控制的完整建模流程。重点介绍了dq坐标系下的解耦控制策略,通过Simulink仿真验证模型准确性,并提供谐振峰偏移、解耦不彻底等实际问题的解决方案,助力电力电子工程师提升系统稳定性。

weixin_28678151的博客 229

Ubuntu 20.04 server 安装

Ubuntu 20.04 server 安装 前面我们介绍了 Ubuntu Desktop 版本的安装,今天我们来看看 Ubuntu server 版本的安装。Ubuntu Server 版本的安装和 Desktop 有很大的区别,并且全程不能使用鼠标,只能通过键盘。 从光盘或 U 盘启动到 Welcome 界面,选择语言,一般都是使用 English,所以保保持默认,直接按回车即可; 系统检测到了新的版本,问你是否是否更新,这里我们不需要安装新的版本,所以选项 Continue without upda

as900的博客 1万+

go中的nil容易踩的坑

来源:公众号【peachesTao】 作者:peachesTao 原文地址:go中的nil容易踩的坑 大家好,我是peachesTao,有2个多月没有更新了,没有达到一个月更新两次的标准,过了个年变得懒散了,现在已找回专注,今天给大家介绍一下go中使用nil时容易踩的坑。 先看一段代码 packagemain import"fmt" typeMyErrorstruct{ Codeint Msgstring } func(e*MyError)Error()st...

taoerchun的专栏 967

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Go 接口值(P1):动态类型与动态值

在讨论 Go 接口时,我们通常会首先关注接口类型本身的定义与使用。然而,仅仅理解接口的声明是不够的。我们有必要进一步探讨它背后运作的核心机制,尤其是**接口值**这一概念。接口值在Go语言中的作用至关重要,它不仅影响到"多态"的实现,还会关系到程序的行为。那么,什么是接口值呢?

Ayanikoji的博客 1751

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Go接口之nil != nil

一、引出话题: 在开始这个话题之前,我们先看一段代码以及其输出结果,代码如下所示: 从上面的输出结果来看,GetA()返回的类型为*A就算赋值为nil,也不等于nil。 看到这里笔者觉得很奇怪,明明是GetA()返回值是nil,为什么nil的判断条件是false呢? 二、原因分析: 在研究了interface之后,笔者发现了真相,原来Go语言中的interface是不...

zhghost的专栏 771

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Golang 需要避免踩的 50 个坑(一)

最近准备写一些关于golang的技术博文,本文是之前在GitHub上看到的golang技术译文,感觉很有帮助,先给各位读者分享一下。 前言 Go 是一门简单有趣的编程语言,与其他语言一样,在使用时不免会遇到很多坑,不过它们大多不是 Go 本身的设计缺陷。如果你刚从其他语言转到 Go,那这篇文章里的坑多半会踩到。 如果花时间学习官方 doc、wiki、讨论邮件列表、 Rob Pike 的大量文章...

aoho求索 3895

接口(Interface)的 Nil 陷阱

Go 的接口是一个带类型的容器。一个空的盒子(Type=nil, Value=nil) 才是nil。一个装着空气的品牌盒子不是nil。

qq_45490502的博客 1169

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

Go 会先将 nil 转换为interface (type=nil, data=nil) ,这与 b (type=*string, data=nil) 虽然 data 是一样的,但 type 不相等,因此他们并不相等。进行判断时,其实右边的 nil 并非单纯的是我们所理解的值为nil,而正确的理解应该是 type 为 nil 且 value 也为 nil。当一个 interface 的 type 和 data 都处于 unset 状态的时候,那么该 interface 的类型和值都为 nil。

Ch3nnn的博客 1842

go nil介绍

在 Go 中,为了简单和方便,nil 被设计为一个标识符,可以用来表示某些类型的零值。他不是一个不变的值,而是随着不同类型有不同的类型,在日常的编码中,编译器会根据上下文来推导出。

daliucheng的博客 1176

golang nil值应用

nil主要是作为slice、map、函数、指针、interface的零值,使用时有两点需要注意: 一、slice的元素清空 package main ​ import ( "fmt" ) ​ func main() { var testList []int fmt.Println("testList1=", testList) testList = ap...

woailuo626的专栏 408

GoLang之nil并不是nil

GoLang之nil并不是nil

weixin_52690231的博客 600

Go语言 nil和interface详解

golang的nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。nil是预先说明的标识符,也即通常意义上的关键字。在golang中,nil只能赋值给指针、channel、func、interface、map或slice类型的变量。如果未遵循这个规则,则会引发panic。对此官方有明确的说明:http://pkg.golang.org/pkg/builtin/#T

Sunface撩技术 3537

Go 语言 nil 和接口

如果你来自其他编程语言,开始学习 Go 编程,那么你很可能会遇到一个既独特又有些令人费解的现象:那就是在 Go 语言中,接口和 nil 指针之间的关系与其他语言大不相同。具体来说,在许多编程语言中,当一个接口或对象引用为 nil(或 null)时,它通常被认为是不存在或无效的。但在 Go 语言中,即使一个接口包含了一个 n...

cnzzs的博客 640

golang 接口与nil的判等

在golang中,nil只能赋值给指针、channel、func、interface、map或slice类型的变量。如果未遵循这个规则,则会引发panic。 nil不能赋值给结构体,编译时会报错 package main import "fmt" type Man struct{ Name string } var ( man Man == nil man1 *Man ) func main () { fmt.Println("man == nil is ",man =

weixin_45161636的博客 765

Go 语言接口变量的nil判断

在go语言的底层,interface类型定义的变量(接口变量)有两个成员变量,一个类型(type)和一个值(value),只有两个都为nil的这个接口变量才是nil,但是如果某个具体的对象赋值给接口变量,无论赋值的对象是不是nil,这个接口变量都不可能是nil。也就是说,即使值部分是nil,只要类型部分不是 nil,接口变量就不是完全意义上的 nil。总之,要判断一个接口变量是否为 nil,你需要检查它的类型和值是否都是 nil。2、现在,我们创建一个。部分是 nil,因为。赋一个非 nil 的。

qq_44644561的博客 567

golang 学习笔记 - struct操作/切片/nil接口值

在看了文章Go 语言的优点,缺点和令人厌恶的设计之后,受益匪浅,觉得需要总结联系一下强化一下记忆。 struct 复制 struct可以通过赋值语句来复制,如下: 虽然y是复制的x,但是修改y内array内容时候,会把x的也改变了。 import "fmt" func main() { x := TestFo{Name: "foo1", Childs: []string{"foo1-2"}} ...

qq_40896725的博客 1379
上一篇: golang踩坑 2.goroutine闭包和遍历字符串字符
下一篇: 基于etcd的服务发现与注册
stackfuture
博客等级 码龄5年 23粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值