Go Language Basics: Notes on Using nil

definition

nilNot a golang keyword, just a variable name . defined buildin/buildin.goin

// nil 是一个预先声明的标识符,表示指针、通道、函数、接口、映射或切片类型的零值。
var nil Type // 类型必须是指针、通道、函数、接口、映射或切片类型
// Type在这里仅用于文档目的。它是任何 Go 类型的替代品,但代表任何给定函数调用的相同类型。
type Type int
复制代码

nilWe can even override it by declaring a variable named by ourselves, of course, this is not recommended.

As seen in the definition's comments, the zero valuenil used to represent a pointer, channel, function, interface, map, or slice type .

zero value

When declaring a variable in golang, if we do not explicitly initialize it, the variable will be assigned a zero value.

type of data zero value
boolean type false
Numeric type 0
string ""
reference type nil

Structures and arrays recursively initialize their fields or elements, whose initial values ​​depend on the element or field.

Panic

assign a value to a null pointer

var i *int
*i = 1    // panic
复制代码

Solution

Allocate a block of memory to a null pointer

var i *int
i = new(int)
*i = 1    // panic
复制代码

get value from null pointer

var i *int
a := *i    // panic
复制代码

Solution

Before assigning, check whether the pointer is empty

var i *int
var a int
if i != nil {
    a = *i
}
// a = 0
复制代码

Interface Type

There is a famous example in golang nil != nil:

var x *int
var y interface{}
fmt.Println(x == nil)    // true
fmt.Println(y == nil)    // true
fmt.Println(x == y)      // false
复制代码

This result is related interfaceto the implementation principle of , and will not be explained in detail here. In short, one interfaceneeds to determine the value through typeand two attributes.value

Add a comment to the above code to make it clear:

var x *int            // type = *int, value = nil
var y interface{}     // type = nil, value = nil
fmt.Println(x == y)   // (*int, nil) == (nil, nil) => false
复制代码

Error handling pit

type MyError struct {}
func (m MyError) Error() string { return "my error" }
func test() error {
   var err *MyError
   return err
}
func main() {
   err := test()
   fmt.Println(err)           // <nil>
   fmt.Println(err == nil)    // false
}
复制代码

We will find that when the value of err is directly output, it is indeed <nil>. When nilcomparing this to , the result is again false.

With the above example, we know that it was test()changed in the erroriginal type, resulting in the final judgment result not meeting expectations.

Guess you like

Origin juejin.im/post/6999169328558014501