初始化空片的正确方法

声明一个空切片,大小不固定, 是否这样做更好:

mySlice1 := make([]int, 0)

或者:

mySlice2 := []int{}

只是想知道哪条路是正确的。

404498 次浏览

它们是等价的。请看下面的代码:

mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))

输出:

mySlice1 0
mySlice2 0

两个切片都有0容量,这意味着两个切片都有0长度(不能大于容量),这意味着两个切片都没有元素。这意味着这两个切片在各个方面都是相同的。

参见类似的问题:

在golang中有nil切片和空切片有什么意义?< / >

空切片vs非空切片vs Go语言中的空切片

你给出的两个选项在语义上是相同的,但是使用make([]int, 0)将导致内部调用runtime.makeslice (Go 1.16)。

你也可以选择保留nil值:

var myslice []int

Golang.org的博客中所写:

一个nil切片在功能上等同于一个零长度的切片,即使它不指向任何东西。它的长度为0,可以通过分配附加到。

正如@farwayer指出的那样,nil片将json.Marshal()编组为"null",而空片将编组为"[]"

正如@ArmanOrdookhani所指出的,上述选项都不会导致任何分配。

空片和空片在Go中的初始化方式不同:

var nilSlice []int
emptySlice1 := make([]int, 0)
emptySlice2 := []int{}


fmt.Println(nilSlice == nil)    // true
fmt.Println(emptySlice1 == nil) // false
fmt.Println(emptySlice2 == nil) // false

对于所有三个切片,len和cap都是0。

作为@ANisus”答案的补充…

下面是一些来自“行动起来”书的信息,我认为值得一提:

nil &empty

如果我们这样想象切片:

[pointer] [length] [capacity]

然后:

nil slice:   [nil][0][0]
empty slice: [addr][0][0] // points to an address

零片

当您想要表示不存在的片时,例如在返回片的函数中发生异常时,它们非常有用。

// Create a nil slice of integers.
var slice []int

空片

当您希望表示空集合时,空片非常有用,例如当数据库查询返回零结果时。

// Use make to create an empty slice of integers.
slice := make([]int, 0)


// Use a slice literal to create an empty slice of integers.
slice := []int{}

不管你使用的是空片还是空片,内置函数appendlencap的工作原理是一样的。


去游乐场的例子:

package main


import (
"fmt"
)


func main() {


var nil_slice []int
var empty_slice = []int{}


fmt.Println(nil_slice == nil, len(nil_slice), cap(nil_slice))
fmt.Println(empty_slice == nil, len(empty_slice), cap(empty_slice))


}

打印:

true 0 0
false 0 0

除了@ANisus的回答

当使用官方Go MongoDb Driver时,nil片也会封送到"null"中,而空片则会封送到"[]"中。

当使用社区支持的分别以司机时,nil和空片都将被编组到"[]"中。

参考:https://jira.mongodb.org/browse/GODRIVER-971