要声明一个具有非固定大小的空切片,最好这样做:
mySlice1 := make([]int, 0)
或者:
mySlice2 := []int{}
只是想知道哪个是正确的方法。
keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }
您提供的两个替代方案在语义上是相同的,但使用 make([]int, 0)
将导致对 runtime.makeslice 的内部调用(Go 1.16)。
您还可以选择将其保留为 nil
值:
var myslice []int
如 Golang.org blog 中所述:
nil 切片在功能上等同于零长度切片,即使它不指向任何内容。它的长度为零,可以通过分配附加到。
但是,正如@farwayer 所指出的,nil
切片将 json.Marshal()
放入 "null"
,而空切片将编组到 "[]"
。
正如@ArmanOrdookhani 所指出的,上述选项都不会导致任何分配。
它们是等价的。请参阅此代码:
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
作为@ANisus'答案的补充......
以下是“Go in action”一书中的一些信息,我认为值得一提:
nil 和空切片之间的区别
如果我们想到这样的切片:
[pointer] [length] [capacity]
然后:
nil slice: [nil][0][0]
empty slice: [addr][0][0] // points to an address
nil slice 当您想要表示不存在的切片时,它们很有用,例如当返回切片的函数中发生异常时。 // 创建一个 nil 整数切片。 var slice []int empty slice 当您想要表示一个空集合时,例如当数据库查询返回零结果时,空切片很有用。 // 使用 make 创建一个空的整数切片。 slice := make([]int, 0) // 使用切片文字创建一个空的整数切片。 slice := []int{} 无论您使用的是 nil 切片还是空切片,内置函数 append、len 和 cap 的工作方式都是一样的。
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
make
一步获得空切片的地址吗?
make
似乎没有返回地址。我相信你不可能一步到位。
空切片和零切片在 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。
make([]int, 0)
是最好的,因为 Jetbrains GoLand 不会像在 []int{}
的情况下那样抱怨它是“不必要的”。这在编写单元测试时很有用。
除了@ANisus 的回答
使用官方 Go MongoDb Driver 时,nil
切片也将编组到 "null"
,而空切片将编组到 "[]"
。
使用社区支持的 MGO driver 时,nil
和空切片都将编组到 "[]"
。
参考:https://jira.mongodb.org/browse/GODRIVER-971
json.Marshal()
将为var myslice []int
返回null
,为已初始化的切片myslice := []int{}
返回[]
reflect.DeepEqual
区分 nil 切片和非 nil 切片:a := []int{}
、var b []int
、reflect.DeepEqual(a, b) // returns false