解释第二行中的行为。最初有两种选择:
- 在第二种情况下输出不会改变
- 输出会改变,最后一个元素会丢失
但还有另一种选择。如何解释?
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
type Item struct {
A int
B string
}
func remove(slice []*Item, s int) []*Item {
return append(slice[:s], slice[s+1:]...)
}
func main() {
x := make([]*Item, 0)
x = append(x, &Item{1, "2"})
x = append(x, &Item{2, "3"})
x = append(x, &Item{3, "4"})
x = append(x, &Item{4, "5"})
fmt.Println(x[0], x[1], x[2], x[3])
remove(x, 0)
fmt.Println(x[0], x[1], x[2], x[3])
x = remove(x, 3)
fmt.Println(x[0], x[1], x[2])
}
&{1 2} &{2 3} &{3 4} &{4 5}
&{2 3} &{3 4} &{4 5} &{4 5}
&{2 3} &{3 4} &{4 5} // 第三个元素会出现恐慌
程序退出。
Go 语言指南,附加和复制切片部分
在函数
remove
中, 指向的数组slice
足够大,可以容纳append
-a 的结果。当调用remove(x, 0)
一个函数时,该remove
值x
被复制。但被复制的不是数组本身,而是它的描述符——一个包含指向数组的指针、类型描述符和元素数量的结构。因此,当您调用 时
remove(x,0)
,操作是在 指向的数组上执行的x
。其中,位置 1,2,3 的元素被复制到位置 0,1,2。位置 3 的元素仍然可用,因为数组描述符x
说“数组中有四个元素”。调用之后,一个新的数组描述符被存储
x = remove(x,3)
在变量中,它表示“数组中有三个元素”。x
结果,最后一个元素不再可见。