英文:
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.yis[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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论