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

go语言中的nil类型

nil定义和概念

  • nil 是 Go 中的预定义标识符,表示某些类型的零值。
  • nil 不是一个关键字,而是一个预声明的标识符。
  • nil 没有默认类型,它可以表示多种类型的零值。

可以为 nil 的类型

指针(Pointers)
接口(Interfaces)
映射(Maps)
切片(Slices)
通道(Channels)
函数(Functions)


不能为 nil 的类型

结构体(Structs)
数组(Arrays)
基本类型(如 int, float, bool, string)

nil 的特性

nil 的内存地址是 0x0。
不同类型的 nil 值可能占用不同的内存大小。
两个 nil 值可能不相等,特别是在接口类型的比较中。

各类型中 nil 的详细说明:

  • a. 指针:

nil 表示空指针,即不指向任何内存地址。
例:var ptr *int = nil

  • b. 接口:

nil 接口既没有类型也没有值。
例:var i interface{} = nil

  • c. 映射:

nil 映射没有任何键值对,且不能添加键值对,但是可以读取数据。
例:var m map[string]int = nil

  • d. 切片:

nil 切片的长度和容量都是 0,且没有底层数组,可以使用append方法。
例:var s []int = nil

  • e. 通道:

nil 通道不能用于通信,会导致永久阻塞,读取和写入数据都不可以。
例:var ch chan int = nil

  • f. 函数:

nil 函数变量表示没有分配任何函数,调用此nil函数会报错。
例:var f func() = nil


nil 的使用和注意事项:

可以用于初始化变量。
在条件语句中常用于检查是否为空。
对 nil 映射的读取操作是安全的,但写入会导致 panic。
对 nil 切片的 append 操作是安全的。
向 nil 通道发送或从中接收会导致永久阻塞。
调用 nil 函数会导致 panic。
nil 与接口的特殊关系:

接口值由类型和值两部分组成。
只有当接口的类型和值都为 nil 时,接口才等于 nil。
这可能导致一些反直觉的比较结果,在后面的例子有给出。

package main

import (
	"fmt"
)

// 定义一个简单的接口
type Speaker interface {
	Speak()
}

// 使用结构体实现接口
type Dog struct{}

func (d Dog) Speak() {
	fmt.Print("woof")
}

func main() {
	// 指针
	var ptr *int = nil
	if ptr == nil {
		fmt.Println("ptr is nil")
	}

	// 接口
	var sp Speaker = nil
	if sp == nil {
		fmt.Sprintln("sp is nil")
	}

	// 映射
	var m map[string]int = nil
	if m == nil {
		fmt.Println("m is nil")
	}

	// 读取nil map中的值是安全的
	fmt.Println("m['a']:", m["a"])
	// 但是写入是不安全的
	// panic: assignment to entry in nil map
	m["a"] = 1

	// 切片
	var s []int = nil
	if s == nil {
		fmt.Println("s is nil")
	}

	// 对nil 切片食用append是安全的
	s = append(s, 1)
	fmt.Println("After append:", s)

	// 通道
	var ch chan int = nil
	if ch == nil {
		fmt.Println("ch is nil")
	}

	// 向 nil 通道中发送数据和读取数据会永久阻塞,以下代码会导致死锁
	// ch <- 1
	// fmt.Println("read from ch:", <-ch)

	// 函数
	var f func() = nil
	if f == nil {
		fmt.Println("function is nil")
	}
	// 调用 nil 函数会导致 panic
	// f()

	// 接口的特殊情况
	var dog *Dog = nil
	var sp2 Speaker = dog
	if sp2 == nil {
		fmt.Println("sp2 is nil")
	} else {
		fmt.Println("sp2 is not nil")
	}
	// 会输出 "sp2 is not nil"
	// 在Go语言中,接口类型的变量由两部分组成:具体的类型和类型的值。当你将一个类型(如*Dog)赋给接口变量时,接口变量会存储这个具体的类型和它的值。

	// 具体类型:在这段代码中,sp2的具体类型是*Dog。
	// 值:虽然dog变量本身是nil,但sp2的值部分存储的是nil。
	// 因此,当你将dog(一个nil的*Dog指针)赋给接口变量sp2时,sp2的类型部分变为*Dog,而值部分是nil。这意味着sp2接口变量本身并不等于nil,因为它的类型部分有一个非nil的类型信息*Dog。

	// 接口的nil判断:
	// 一个接口变量只有在其类型和值的部分同时为nil时,才会被认为是nil。
	// 在这种情况下,虽然sp2的值是nil,但它的类型部分是*Dog,因此sp2不等于nil。

}


http://www.kler.cn/a/381757.html

相关文章:

  • 大语言模型学习工具及资源总结和落地应用
  • 重生之我在异世界学编程之C语言:深入预处理篇(上)
  • uni-app 统一请求处理 请求拦截器 响应拦截器 请求封装
  • Kafka快速扫描
  • 我用Cursor+DeepSeek做了个飞书文档一键同步插件,免费使用!
  • 信号仿真高级工程师面试题
  • debian系统安装qt的时候 显示xcb相关文件缺失
  • 在培训班学网络安全有用吗
  • 【maven】idea执行了maven的install命令给本地安装项目依赖包 安装后删除
  • Python使用爬虫
  • CSS Position 定位如何使用?
  • 5个有效的华为(HUAWEI)手机数据恢复方法
  • java项目之校园周边美食探索及分享平台(springboot)
  • Neo4j入门:详解Cypher查询语言中的MATCH语句
  • [论文阅读]BERT-based Lexical Substitution
  • 写文件回前端进行下载,报错:原因:CORS 头缺少 ‘Access-Control-Allow-Origin‘)
  • 青少年编程与数学 02-003 Go语言网络编程 10课题、HTTP/HTTPS协议
  • PDF全能免费转换 3.18 | 免费PDF工具集,多种转换和美化功能
  • 前后端理解、API接口
  • Caffeine 手动策略缓存 put() 方法源码解析
  • Java基础-组件及事件处理(上)
  • Qt 环境实现视频和音频播放
  • 【C++的vector、list、stack、queue用法简单介绍】
  • Oracle OCP认证考试考点详解082系列09
  • 使用Centos搭建Rocket.Chat教程
  • 融合智能化和信息化的技术的智慧地产开源了。