由于@james-henstridge 的回答已经涵盖了如何让它发挥作用,我不会重复他所说的内容,但我会解释 为什么 他的回答有效。

[3]int[4]int
 a := [3]int{1, 2, 3} // Array literal
b := a               // Copy the contents of a into b
a[0] = 0
fmt.Println(a)       // Prints "[0 2 3]"
fmt.Println(b)       // Prints "[1 2 3]"

[]int
 a := []int{1, 2, 3} // Slice literal
b := a              // a and b now point to the same memory
a[0] = 0
fmt.Println(a)      // Prints "[0 2 3]"
fmt.Println(b)      // Prints "[0 2 3]"

执行

如果这个解释很容易理解,那么您可能也想知道它是如何实现的(如果您难以理解,我会停止阅读这里,因为细节可能会令人困惑)。

在幕后,Go 切片实际上是结构。它们有一个指向已分配内存的指针,就像我提到的,但它们还有另外两个关键组成部分:长度和容量。如果用 Go 术语来描述,它看起来像这样:

 type int-slice struct {
    data *int
    len  int
    cap  int
}

len(mySlice)
make([]int, 3)
slc[a:b]slcab
 a := [5]int{1, 2, 3, 4, 5}
b := a[1:4]
fmt.Println(b) // Prints "[2 3 4]"

a
   begin     end  // a
  v         v
[ 1 2 3 4 5 ]
    ^     ^
    begin end    // b

b
 a := []int{1, 2, 3}
b := a[0:1]
fmt.Println(b) // Prints "[1]"
b = b[0:3]
fmt.Println(b) // Prints "[1 2 3]"

b[0:3]b

原文由 joshlf 发布,翻译遵循 CC BY-SA 4.0 许可协议