提问人:eouti 提问时间:3/20/2015 最后编辑:eouti 更新时间:6/24/2021 访问量:482195
初始化空切片的正确方法
Correct way to initialize empty slice
问:
要声明一个大小不固定的空切片, 这样做更好吗:
mySlice1 := make([]int, 0)
艺术
mySlice2 := []int{}
只是想知道哪一个是正确的方法。
答:
它们是等价的。请参阅此代码:
mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))
输出:
mySlice1 0
mySlice2 0
两个切片都具有容量,这意味着两个切片都有长度(不能大于容量),这意味着两个切片都没有元素。这意味着 2 个切片在各个方面都是相同的。0
0
查看类似问题:
在 golang 中拥有 nil slice 和 empty slice 有什么意义?
Go 语言中的 nil 切片 vs 非 nil 切片 vs 空切片
您给出的两个替代方案在语义上是相同的,但使用将导致对 runtime.makeslice (Go 1.16) 的内部调用。make([]int, 0)
您还可以选择将其保留为一个值:nil
var myslice []int
正如 Golang.org 博客中所写:
零切片在功能上等同于零长度切片,即使它不指向任何内容。它的长度为零,可以附加到分配中。
然而,一个切片将进入,而一个空切片将编组成,正如@farwayer所指出的。nil
json.Marshal()
"null"
"[]"
正如@ArmanOrdookhani所指出的,上述选项都不会造成任何分配。
评论
json.Marshal()
null
var myslice []int
[]
myslice := []int{}
reflect.DeepEqual
a := []int{}
var b []int
reflect.DeepEqual(a, b) // returns false
runtime.zerobase
。
这意味着,Go 1.16 中的文字速度略快。
空切片和零切片在 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 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 切片还是空切片,内置函数 、 和 的工作方式都是一样的。
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
除了@ANisus的回答
使用官方的 Go MongoDb 驱动程序时,切片也会编组成,而空切片将编组成 .nil
"null"
"[]"
使用社区支持的 MGO 驱动程序时,空切片和空切片都将封组到 .nil
"[]"
评论
keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }