英文:
Why does a slice expression of an empty slice have values in it?
问题
刚开始学习Golang,对切片表达式有些困惑。
这段代码的输出结果是:
[] [20] [20 0] [20 0]
我对这段代码的理解如下:
-
x := make([]int, 0, 5)
- 创建一个新的 int 类型切片,长度为 0,容量为 5。 -
y := append(x, 20)
- 使用 append 函数创建一个新的切片,长度为 1,容量为 5,y
的值为[20]
。 -
fmt.Println(x, y, x[:2], y[:2])
x[:2]
为什么输出[20 0]
?它不应该导致错误吗?如果这是一个切片表达式创建一个新的切片,它不应该是[0 0]
吗?第一个值为什么是 20?
我在这里可能缺少一些基本概念。
如果我要猜测的话,我认为使用 y := append(x, 20)
创建的 y
切片与底层数组共享内存。当我直接打印 x
时,这一点并不明显,但当我打印 x[:2]
时就能看到。
英文:
Just started leaning Golang. Facing some trouble understanding the slice expression.
package main
import "fmt"
func main() {
x := make([]int, 0, 5)
y := append(x, 20)
fmt.Println(x, y, x[:2], y[:2])
}
Output:
[] [20] [20 0] [20 0]
Here's my understanding of what this represents:
-
x := make([]int, 0, 5)
- make a new slice of ints with 0 length and 5 capacity. -
y := append(x, 20)
- create a a new slice using append function with length 1 & capacity of 5.y
is[20]
. -
fmt.Println(x, y, x[:2], y[:2])
- How does
x[:2]
print[20 0]
? Shouldn't it just cause an error? If this was the slice expression creating a new slice shouldn't it be[0 0]
? How is the first value 20?
- How does
I am missing some fundamental concept here.
If I were to take a guess I think creating y using y := append(x, 20)
is somehow sharing the underlying memory. This is not shown when I print x
directly, but when I am printing x[:2]
it is shown.
答案1
得分: 3
> y := append(x, 20) - 使用append函数创建一个新的切片,长度为1,容量为5。y为[20]。
这是不正确的。因为已经有可用的容量,所以它不会分配一个新的数组。这就是预先分配容量大于长度的切片的整个目的。
x := make([]int, 0, 5)
会生成一个切片[],底层数组为[0, 0, 0, 0, 0]。
y := append(x, 20)
会生成一个切片[20],底层数组仍为[20, 0, 0, 0, 0]。
fmt.Println(x, y, x[:2], y[:2])
会产生四个切片:
x = [] //(长度和容量未改变)
y = [20] //(参见上面的append解释)
x[:2] = [20, 0] //(底层数组的前两个元素)
y[:2] = [20, 0] //(同一个数组的相同两个元素)
英文:
> y := append(x, 20) - create a a new slice using append function with length 1 & capacity of 5. y is [20].
Not true. Because there is capacity already available, it does not allocate a new array. That is the whole point of pre-allocating a slice with capacity greater than its length.
x := make([]int, 0, 5)
Yields a slice [] over an array [0, 0, 0, 0, 0].
y := append(x, 20)
Yields a slice [20] over the same array, now [20, 0, 0, 0, 0].
fmt.Println(x, y, x[:2], y[:2])
Produces four slices:
x = [] // (its length & cap haven't changed)
y = [20] // (see append explanation above)
x[:2] = [20, 0] // (first two elements of the underlying array)
y[:2] = [20, 0] // (same two elements of the same array)
This is covered in detail in the Tour of Go and in further detail on the Go blog.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论