英文:
Correct way to initialize empty slice
问题
声明一个空的切片,且大小不固定,哪种方式更好呢?
是这样做更好:
mySlice1 := make([]int, 0)
还是这样做更好:
mySlice2 := []int{}
只是想知道哪种方式是正确的。
英文:
To declare an empty slice, with a non-fixed size,
is it better to do:
mySlice1 := make([]int, 0)
or:
mySlice2 := []int{}
Just wondering which one is the correct way.
答案1
得分: 453
你给出的两个选择在语义上是相同的,但是使用make([]int, 0)
会导致内部调用runtime.makeslice(Go 1.16)。
你还可以选择将其保留为nil
值:
var myslice []int
正如Golang.org博客中所述:
> 尽管nil
切片指向空,但在功能上与零长度切片等效。它的长度为零,可以进行追加分配。
nil
切片在进行json.Marshal()
时将转换为"null"
,而空切片将转换为"[]"
,如@farwayer所指出的。
如@ArmanOrdookhani所指出的,以上任何选项都不会导致任何分配。
英文:
The two alternative you gave are semantically identical, but using make([]int, 0)
will result in an internal call to runtime.makeslice (Go 1.16).
You also have the option to leave it with a nil
value:
var myslice []int
As written in the Golang.org blog:
> a nil slice is functionally equivalent to a zero-length slice, even though it points to nothing. It has length zero and can be appended to, with allocation.
A nil
slice will however json.Marshal()
into "null"
whereas an empty slice will marshal into "[]"
, as pointed out by @farwayer.
None of the above options will cause any allocation, as pointed out by @ArmanOrdookhani.
答案2
得分: 129
它们是等价的。看看这段代码:
mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))
输出结果:
mySlice1 0
mySlice2 0
两个切片的容量都为0
,这意味着两个切片的长度也都为0
(长度不能大于容量),这意味着两个切片都没有元素。这意味着这两个切片在每个方面都是相同的。
参考类似的问题:
英文:
They are equivalent. See this code:
mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))
Output:
mySlice1 0
mySlice2 0
Both slices have 0
capacity which implies both slices have 0
length (cannot be greater than the capacity) which implies both slices have no elements. This means the 2 slices are identical in every aspect.
See similar questions:
答案3
得分: 66
作为对@ANisus'回答的补充...
以下是我认为值得一提的来自《Go语言实战》一书的一些信息:
nil
切片与空切片的区别
如果我们将切片表示为:
[指针] [长度] [容量]
那么:
nil切片: [nil][0][0]
空切片: [地址][0][0] // 指向一个地址
nil切片
当你想表示一个不存在的切片时,比如在返回切片的函数中发生异常时,它们非常有用。
// 创建一个整型的nil切片。
var slice []int
空切片
当你想表示一个空的集合时,比如数据库查询返回零结果时,空切片非常有用。
// 使用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
英文:
As an addition to @ANisus' answer...
below is some information from the "Go in action" book, which I think is worth mentioning:
Difference between nil
& empty
slices
If we think of a slice like this:
[pointer] [length] [capacity]
then:
nil slice: [nil][0][0]
empty slice: [addr][0][0] // points to an address
>### nil slice
They’re useful when you want to represent a slice that doesn’t exist, such as when an exception occurs in a function that returns a slice.
>
// Create a nil slice of integers.
var slice []int
> ### empty slice
Empty slices are useful when you want to represent an empty collection, such as when a database query returns zero results.
>
// 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{}
>Regardless of whether you’re using a nil slice or an empty slice, the built-in functions append
, len
, and cap
work the same.
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))
}
prints:
true 0 0
false 0 0
答案4
得分: 18
空切片和nil切片在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。
英文:
Empty slice and nil slice are initialized differently in 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
As for all three slices, len and cap are 0.
答案5
得分: 2
除了 @ANisus 的回答之外,
当使用官方的 Go MongoDb Driver 时,一个 nil
切片也会被编组为 "null"
,而一个空切片会被编组为 "[]"
。
当使用社区支持的 MGO driver 时,nil
和空切片都会被编组为 "[]"
。
参考:https://jira.mongodb.org/browse/GODRIVER-971
英文:
In addition to @ANisus' answer
When using the official Go MongoDb Driver, a nil
slice will also marshal into "null"
whereas an empty slice will marshal into "[]"
.
When using using the community supported MGO driver, both nil
and empty slices will be marshalled into "[]"
.
Reference: https://jira.mongodb.org/browse/GODRIVER-971
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论