为什么有些切片是空的?

huangapple go评论109阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年2月25日 03:49:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75560796.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定