正确初始化空切片的方法

时间:2015-03-20 10:27:56

标签: arrays go slice

要声明一个非固定大小的空切片, 是不是更好:

mySlice1 := make([]int, 0)

或:

mySlice2 := []int{}

只是想知道哪一个是正确的方法。

5 个答案:

答案 0 :(得分:202)

你给出的两个替代方案在语义上是相同的,我认为它们会产生相同的汇编指令。

为避免不必要的分配,如果您最终不使用切片,可以保留nil值:

var myslice []int

正如Golang.org blog所述:

  

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

答案 1 :(得分:47)

它们是等价的。看到这段代码:

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

输出:

mySlice1 0
mySlice2 0

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

见类似问题:

What is the point of having nil slice and empty slice in golang?

nil slices vs non-nil slices vs empty slices in Go language

答案 2 :(得分:31)

作为@ANisus'回答的补充......

以下是“Go in action”一书中的一些信息,我认为值得一提:

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{}
     

无论您使用的是nil切片还是空切片,内置函数appendlencap的工作方式都相同。

Go playground example

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

答案 3 :(得分:11)

在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。

答案 4 :(得分:0)

除了@ANisus 的回答

使用官方 Go MongoDb Driver 时,nil 切片也会编组到 "null" 中,而空切片将编组到 "[]" 中。

使用社区支持的 MGO driver 时,nil 和空切片都将被编组到 "[]" 中。

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