In Golang nil
, many people mistakenly think of NULL in programming languages such as Java, PHP, and so on. But actually Golang's niu is much more complicated, and if not, let's continue reading.
nil
For pre-declared identifiers, defined in builtin/builtin.go
,
Nil value of 0
According to the Go Language specification, any type has a value of 0 when uninitialized: The Boolean type is False, the integer is 0, the string is "", and the 0 values for pointers, functions, interface, slice, channel, and map are nil.
PS: This does not say that the struct struct's 0 value is nil, because the struct's 0 value is related to its properties
nil
does not have a default type, although it is a 0 value of more than one type, you must explicitly or implicitly specify the explicit type of each nil usage.
nil , that is nil
is not a keyword, you can define nil
, nil
will be hidden.
Package Mainimport "FMT" Func main () {nil: = 123fmt. Println (nil)//123var _ Map[string]int = nil//cannot use nil (type int.) as type Map[string]int in assignment}
The address and value size of the nil type
nil
The memory layout of all values of a type is always the same, in other words: Different types nil
of memory addresses are the same.
Package Mainimport ("FMT") func main () {var m map[int]stringvar ptr *intvar sl []intfmt. Printf ("%p\n", m)//0x0fmt. Printf ("%p\n", PTR)//0x0fmt. Printf ("%p\n", SL)//0x0}
The business will generally nil
value is represented as an exception. The size of the nil value is always the same as its type nil
value non-nil
value is the same size. Therefore, a nil identifier that represents a different 0 value may have a different size.
The size is dependent on the compiler and architecture. The above print results are 64-bit architecture and the official Go compiler. For a 32-bit architecture, the size of the print will be half.
For the official Go compiler, the same kind of different types of two nil values are always the same size. For example, the two nil values for two different tile types ([]int and []string] are always the same.
Nil value Comparison
1. Different types nil
are not comparable.
Package Mainimport ("FMT") func main () {var m map[int]stringvar ptr *intfmt. Printf (M = = ptr)//invalid operation:m = = PTR (mismatched types map[int]string and *int)}
In Go, two values of two different comparable types can be compared only if one value can be implicitly converted to another type. Specifically, there are two cases with two different values that can be compared:
nil
The value comparison does not deviate from the above rule.
Package Mainimport ("FMT") func main () {type IntPtr *intfmt. Println (IntPtr (nil) = = (*int) (nil))//truefmt. Println ((interface{}) (nil) = = (*int) (nil))//false}
2. Two values of the same type nil
may not be compared because the presence of map, slice, and function types in Golang are not comparable types, and they have one that is not 不可比拟的类型
, so it nil
is also illegal to compare them.
Package Mainimport ("FMT") func main () {var v1 []int = Nilvar v2 []int = nilfmt. Println (v1 = = v2) fmt. Println ((Map[string]int) (nil) = = (Map[string]int) (nil)) FMT. Println ((func ()) (nil) = = (Func ()) (nil))}
不可比拟的类型
The value of the missing is comparable to "pure nil".
Package Mainimport ("FMT") func main () {FMT. Println ((Map[string]int) (nil) = = nil)//truefmt. Println ((func ()) (nil) = = nil)//true}
3. Two nil
values may not be equal
If one of the two compared nil values is an interface value, and the other is not, assuming that they are comparable, the comparison result is always false. The reason is that the interface value is converted to the type of the interface value before the comparison is made. The converted interface value has a specific dynamic type, but the other interface values are not. That's why the comparison is always wrong.
Package Mainimport ("FMT") func main () {FMT. Println ((interface{}) (nil) = = (*int) (nil))//False}
Problems
1. function return
Func Nilreturn () (string,error) {return nil,nil//cannot use nil as type string in return argument}
error
the error
type does not have an error because it is an interface type.
The key for the 2.map nil key map is pointer, function, interface, slice, channel, and map, then key can be nil.
Package Mainimport ("FMT") func main () {mmap: = Make (map[*string]int,4) a:= "a" mmap[&a] = 1mmap[nil] = 99fmt. Println (mmap)//map[0xc042008220:1 <nil>:99]}
Summarize
Nil is more difficult to understand because we often confuse the nil value and nil type, I hope you students savor the difference.