nil
在Go语言中,nil
是一种特殊值,主要用于指针、接口、切片、映射、通道这五种引用类型。与其它类型的默认值(零值)有着显著的区别:
-
nil:
-
nil
表示没有具体的值或不存在的对象引用。它可以赋值给指针、切片、映射、通道和接口类型。 -
当一个指针变量被赋予
nil
时,它不再指向任何内存地址。 -
当切片、映射或通道被赋予
nil
时,它们是未初始化的状态,不能进行任何操作(如访问、插入元素等),否则会导致 panic。 -
接口变量被赋予
nil
时,表示接口没有任何具体类型实现。 -
nil标识符不能用来做比较。
-
不同类型的 nil 是不能比较的。
-
两个相同类型的 nil 值也可能无法比较。
-
不同类型的 nil 值占用的内存大小可能是不一样的
-
-
其他类型默认值(零值):
- 基本类型(如整型、浮点型、布尔型、字符串等):它们的零值分别是整数0、浮点数0.0、布尔值
false
和空字符串""
。 - 结构体、数组和复合类型:它们的成员变量或元素都将被初始化为各自类型的零值。
- 函数类型:函数类型的零值是
nil
,但这个nil
指的是函数指针没有指向任何函数,而不是函数本身具有一个特殊的值。
- 基本类型(如整型、浮点型、布尔型、字符串等):它们的零值分别是整数0、浮点数0.0、布尔值
总结起来,nil
与非引用类型默认值(零值)的主要区别在于:
nil
仅针对特定类型的变量,且表示没有有效对象或者未初始化的状态。- 其他类型(尤其是非引用类型)的默认值是固定的、明确的初始值,这些值是类型固有的,并且可以被正常使用的(尽管可能是无效的业务状态,如空字符串仍然可以作为字符串使用,只是不包含任何字符)。
new
函数
- 功能 :
new
函数用于分配指定类型的新实例,并将其初始化为其零值。它返回的是一个指向新分配类型值的指针。 - 语法 :
new(T)
,其中T
是你想要分配的类型。 - 应用范围 :
new
可以用于任何类型,包括但不限于结构体、数组、指针、基本类型等。 - 返回值 :返回的是指向新分配内存的指针,类型为
*T
。 - 内存初始化:分配的内存区域都会被清零,即包含的值为相应类型的零值。
make
函数
- 功能 :
make
函数专门用于初始化并返回三种特殊的引用类型:切片(slice)、映射(map)和通道(channel)。它不仅分配内存,还会做额外的初始化工作,这些类型在使用前必须经过初始化,不能直接使用new
函数。- 对于切片,
make
会分配底层数组的内存,并初始化切片结构体,包括长度和容量信息。 - 对于映射,
make
初始化一个空的映射哈希表。 - 对于通道,
make
初始化一个通信信道,可以设定缓冲区大小。
- 对于切片,
- 语法 :
make(T, args...)
,这里的T
必须是 slice、map 或 channel 类型,args...
根据不同类型的初始化要求提供额外参数(如切片的长度和容量,或通道的缓冲大小)。 - 返回值:返回的是初始化完成后的 slice、map 或 channel 类型自身,而不是它们的指针。
- 内存初始化:make 不仅仅是分配内存,还会根据不同的类型进行相应的初始化过程,对于映射和通道,它们内部的数据结构会准备好用于存放元素和执行通信。
总结:
- 使用
new
主要是为任意类型分配内存并初始化为零值,然后返回指向该内存的指针。 - 使用
make
仅限于初始化切片、映射和通道,并完成这些类型特有的初始化过程,以便能够正常使用它们的特性和功能。