文章目录

  • nil
    • slice
    • map
  • interface
    • 指针是否为空

Go语言中任何类型在未初始化时都对应一个零值:布尔类型是false,整型是0,字符串是"",而指针、函数、interface、slice、channel和map的零值都是nil。

nil

Go中,每个指针都有2个基本信息,指针的类型和指针的值(type,value);当执行==时,需要比较类型与值(只有类型与值都相等时,才会相等)。

nil并不是Go语言的关键字或者保留字,而是一个预定义好的标识符:

  • nil之间不能比较:nil==nil是不允许的,会抛出operator == not defined on untyped nil异常;
  • 不同类型的nil之间不能互相比较:如切片的nil,不能与map的nil做比较;
  • nil是map、slice、pointer、channel、func、interface的零值;
  • 不同类型nil值占用空间可能大小不同;

在64位机器上运行时nil的大小:

func main() {var p *struct{}fmt.Println(unsafe.Sizeof(p), p == nil) // 8var s []intfmt.Println(unsafe.Sizeof(s), s == nil) // 24var m map[int]boolfmt.Println(unsafe.Sizeof(m), m == nil) // 8var c chan stringfmt.Println(unsafe.Sizeof(c), c == nil) // 8var f func()fmt.Println(unsafe.Sizeof(f), f == nil) // 8var i interface{}fmt.Println(unsafe.Sizeof(i), i == nil) // 16
}

slice

一个nil的slice,除了不能索引外,其他的操作都正常;当append元素时,slice会自动进行扩容。

slice是一个简单的结构体,包含(长度、容量、指向数组的指针);当slice为nil时,长度、容量都为0,指针为空。

map

一个nil的map,是一个真正的空指针,除len与for-range外,其他操作不能正常使用

非nil的map,是一个指向内部HashMap的指针;空map(map[string]int{})与为nil的map是不同的,空map只是没有内容,可在上面做任何的map操作。

interface

interface底层由两部分组成(参见《golang反射简介》),一个是类型,一个值,也就是类似于:(Type, Value)。只有当类型和值都是nil的时候,才等于nil:

func inFun(v interface{}) {fmt.Println("fun-interface:", v == nil)
}func main() {var a interface{}var b []stringvar c stringfmt.Println(a == nil)inFun(a)    // truefmt.Println(b == nil)inFun(b)    // false//fmt.Println(c == nil) // can not compare with nilinFun(c)    // false
}// true
// fun-interface: true
// true
// fun-interface: false
// fun-interface: false

本身是interface时,传递interface参数,其nil属性不变;若是普通指针,则传递给interface参数时,都为非空(!=nil)

指针是否为空

那如何判定interface里面的动态值是否空?此时需要借助反射reflect来实现:

func nilCheck(v interface{}) {defer func() {if err := recover(); err != nil {fmt.Println("panic:", err)}}()if v == nil {fmt.Println("nilCheck: interface is nil")return}vi := reflect.ValueOf(v)fmt.Println("nilCheck:", vi.IsNil())
}func main() {var a interface{}var b []stringvar c stringnilCheck(a)nilCheck(b)nilCheck(c)
}// nilCheck: interface is nil
// nilCheck: true
// panic: reflect: call of reflect.Value.IsNil on string Value

对于非指针类型,在反射后调用IsNil时会抛出异常。其实现:

func (v Value) IsNil() bool {k := v.kind()switch k {case Chan, Func, Map, Pointer, UnsafePointer:if v.flag&flagMethod != 0 {return false}ptr := v.ptrif v.flag&flagIndir != 0 {ptr = *(*unsafe.Pointer)(ptr)}return ptr == nilcase Interface, Slice:// Both interface and slice are nil if first word is 0.// Both are always bigger than a word; assume flagIndir.return *(*unsafe.Pointer)(v.ptr) == nil}panic(&ValueError{"reflect.Value.IsNil", v.kind()})
}

[go]空nil与interface中的空指针相关推荐

  1. java中避免空指针_在Java中避免空检查

    java中避免空指针 对于Java开发人员(从初级到专家)最糟糕的噩梦之一是空对象引用检查. 我很确定您已经看过几次这样的代码: public void addAddressToCustomer(Cu ...

  2. 如何判断map为空_在Java中如何优雅地判空

    来自:李良逸 链接:http://blog.imuxuan.com/archives/86 判空灾难 作为搬砖党的一族们,我们对判空一定再熟悉不过了,不要跟我说你很少进行判空,除非你喜欢 NullPo ...

  3. 关于开发过程中的空指针问题

    关于开发过程中的空指针问题 从以下角度来说明怎么在一定程序上,合理避免这个问题. public字段的使用 多层局部变量调用所产生的NullPointException问题 public字段的使用 其实 ...

  4. C语言中的空指针、空指针常量、NULL 0

    C语言中的空指针.空指针常量.NULL & 0  本文转自: http://bbs.chinaunix.net/viewthread.php?tid=544415&extra=& ...

  5. java中常量定义在interface中好还是定义在class中

    Java中interface中定义变量都是"public static final" 类型的, 也就是常量, 因此很多人在interface定义常用的常量,除此之外单独定义一个cl ...

  6. (三)01 -Vue项目打包发布移动App——vue.config.js中配置相对路径publicPath为空字符串 在public中添加HBuilderX的打包配置文件manifest.json

    Vue 项目打包发布移动 App--npm run build打包 & vue.config.js文件中配置相对路径publicPath为空字符串 & 在 public中添加HBuil ...

  7. 【Java 基础】静态常量放在 class 类中还是放在 interface 中

    一.放在 class 类中 package com.example.demo.utils;public class ParamUtils {private ParamUtils() {}public ...

  8. 数字通信理论在空时编码估计中的应用

    多入多出技术(Multiple- Input Multiple- Output, MIMO)是无线通信领域技术上的重大突破.该技术能在不增加带宽的情况下成倍地提高通信系统的容量和频谱利用率,突破了香农 ...

  9. Java中常量定义在interface中好还是定义在class中好(常量接口模式)

    java中interface中定义变量都是"public static final" 类型的, 也就是常量, 因此很多人在interface定义常用的常量(这也是本人偏爱的方式); ...

最新文章

  1. 【Python】list转str
  2. Ubuntu 上更新 Flash 插件
  3. 微软将在英国投入20亿Bing广告 挑战Google的统治地位
  4. leetcode-sort-colors
  5. linux安装外部软件,科学网—Madagascar 软件安装方法(Ubuntu下,适用于其他Linux系统) - 罗飞的博文...
  6. 云服务器软件运行出错,云服务器程序运行中出现木马
  7. 华为发布IdeaHub S2系列,与华为云会议结合更强大
  8. 在web服务器上运行html文件,再调用cgi打开txt文件
  9. win11的控制面板在哪?
  10. 请开启微信或者手机定位服务器,微信在哪里设置定位(微信开启定位功能设置)...
  11. HTML期末大作业~仿小米商城网页设计模板(HTML+CSS+JavaScript)
  12. Apache的Order Allow,Deny 配置详解
  13. 万字长文!Unix 和 Linux 你不知道的那些历史(详解版)
  14. 奥维奥:新零售下,家具家居该如何乘风破浪?
  15. CSK KCF(tracking)
  16. transform:rotate兼容
  17. 拥有无数个智能摄像头,却还没让城市睁开双眼
  18. 自清洗袋式过滤器的自清洗方法
  19. oracle_pdb_sid,Oracle12c多租户数据库 - PDB数据库的unplug及plug 1
  20. 拉格朗日启发式算法matlab,基于时间满意的最大覆盖选址问题

热门文章

  1. 10种常见的软件架构模式
  2. 【论文笔记】论文清单备忘录
  3. 现在,就开始:学会学习,学会成长
  4. 入托不焦虑 | 如何帮宝宝更好地融入托班?
  5. 时间 Date 循环计时器
  6. 《关系攻略》自我学习攻略
  7. 【IT系列之5】以IT高新科技为主力军的知识经济时代的政治与战争
  8. 学习分享 | 通过C++,python的对比,帮你快速入门python
  9. input 属性为 number,maxlength不起作用如何解决?
  10. Rockland Mcl-1抗体说明书