Go - 指针声明

2022-01-09 · xiejiahe

在大部分时候初始化变量我们会这么做:

var n int
// 或者
n := 0

上面的代码实际上是等价的,没有问题, 但是在切片就不同了,看下面例子:

var sliceN1 []int // 结果为 nil

sliceN2 := []int{} // 结果为 []

这TM是一个坑啊,官方是这么解释的:

When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value. Each element of such a variable or value is set to the zero value for its type: false for booleans, 0 for numeric types, “” for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.

官方文档指出切片在没有初始化的情况下切换的零值是 nil , 第一种是未初始化,第二种是初始化为空,所以这2种声明都是不等价的,也就是 nil != slice。 在开发过程中需要注意。

还有一种区别就是在 json 转换时 nil 会被当成 null, 而另外一种是被当初 [] 空数组。 在WEB开发中完全是坑。

var n []string
r, _ := json.Marshal(n)
fmt.Println(string(r)) // "null"


n := []string{}
r, _ := json.Marshal(n)
fmt.Println(string(r)) // "[]"

如果我们使用第二种初始化,就会被 Goland 认为是一种冗余的写法,会让你转换为第一种 var, 这样就又出刚刚说的问题了。

有人说这是 Goland 的 Bug, Goland 团队认为 nil切片在功能上等同于零长度切片,即使它不指向任何内容

解决办法是使用 make

var n []int = make([]int, 0) // 全局
sliceN := make([]int, 0) // 函数内

我的建议就是在声明切片时都使用 make 来初始化,防止入坑。

Golang
原创文章,转载请注明出处。