英文:
Why are some slices nil?
问题
我整理了这段代码来展示我的困惑:
https://go.dev/play/p/HVp7p0w74Un
这两个切片,x和y,在数据(无)的、长度和容量方面是相同的。但其中一个是nil,另一个不是。我知道这是一个事实,但我不明白为什么会这样。
基本上,我正在尝试学习Go语言,但我不知道如何思考这个问题以便记住它。
那么,为什么x的值为nil而y的值不是呢?
英文:
I put together this code to demonstrate my confusion:
https://go.dev/play/p/HVp7p0w74Un
the two slices, x and y are identical in terms of data (none), length and capacity. But one of them is nil and the other is not. I understand this as a fact but I don't understand WHY it should be the case.
Basically I'm trying to learn Go and I don't know how to think about this in order to remember it.
So, why does x evaluate to nil while y does not?
答案1
得分: 2
一个切片只有在它指向的底层数组为nil时才为nil。如果一个切片被初始化,即使它的容量为零,它也不是nil。这在区分未初始化的切片和长度为0的切片时很有用。
在你的程序中,你可以将切片y
赋值为nil:
y := make([]int, 0)
fmt.Println(y, len(y), cap(y)) // [] 0 0
fmt.Println(y == nil) // false
y = nil
fmt.Println(y == nil) // true
fmt.Println(y, len(y), cap(y)) // [] 0 0
英文:
A slice is nil if the underlying array it points to is nil. If a slice is initialized, even if it's capacity is zero, it is not nil. This is useful in distinguishing between an uninitialized slice and a slice of length 0.
In your program, you can assign the slice y
to nil:
y := make([]int, 0)
fmt.Println(y, len(y), cap(y)) // [] 0 0
fmt.Println(y == nil) // false
y = nil
fmt.Println(y == nil) // true
fmt.Println(y, len(y), cap(y)) // [] 0 0
答案2
得分: 1
《Go编程语言规范》
零值
当为变量分配存储空间时,无论是通过声明还是通过调用new,或者当创建一个新值时,无论是通过复合字面量还是通过调用make,如果没有提供显式初始化,变量或值将被赋予默认值。这样的变量或值的每个元素都被设置为其类型的零值:布尔类型为false,数值类型为0,字符串类型为"",指针、函数、接口、切片、通道和映射类型为nil。
切片的零值是nil
。
切片的实现
type slice struct {
array unsafe.Pointer
len int
cap int
}
零值是每个struct
字段的二进制零值。
英文:
> The Go Programming Language Specification
>
> The zero value
>
> When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value. Each element of such a variable or value is set to the zero value for its type: false for booleans, 0 for numeric types, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps.
The zero value for a slice is nil
.
The implementation of a slice
type slice struct {
array unsafe.Pointer
len int
cap int
}
The zero value is the zero value for each of the struct
fields, that is binary zero each of the struct
fields.
答案3
得分: 1
当你像这样声明一个切片 var x []int
时,你创建了一个空切片。
实际上,你告诉编译器的是:"创建一个类型为 []int 的切片",由于没有赋值,x 被赋予了切片的零值,即 nil。
如果你不想它是 nil,你需要使用一个非 nil 的字面量来表示 var x []int{}
。
在这里,{}
是一个空数组字面量,空并不意味着 nil,所以这个切片不是一个 nil 切片。
这与声明 y := make([]int, 0)
是等价的。
你也可以使用数组字面量来初始化切片的一些值:var x []int{1, 2, 3}
。
英文:
When you declare a slice like this var x []int
you are creating a nil slice.
What you are actually telling the compiler is: "create a slice of type []int" and since no value is assigned, x is assigned the zero
value for a slice, which is nil.
If you don't want it to be nil you need to express it with a non nil literal var x []int{}
Here {}
is an empty array literal and empty doesn't mean nil so this slice is not a nil slice.
This is somehow equivalent to declaring y := make([]int, 0)
.
You could also initialize a slice with some values in the array literal: var x []int{1, 2, 3}
答案4
得分: 0
在Go语言中,make函数会根据capacity参数分配内存空间,因此它会返回一个非nil的引用。如果没有使用make函数,只是声明了切片但没有分配内存空间,那么它将引用nil。
英文:
make function in Go, will allocate memory as specified in the capacity parameter. Therefore, it has a non-nil reference. Without make, it will only declare the slice but won't allocate memory space. Therefore, it refers to nil.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论