【发布时间】:2019-05-19 16:53:18
【问题描述】:
main 声明了一个名称为 allOutputs 的切片(我相信它是字符串切片,而不是字符串数组),长度为零,容量为 100。然后它附加一个值为“abcd”的字符串并调用 myTest 函数,该函数将数组 [0] 更新为“1234”,然后附加一个值为“5678”。
当我在调用myTest 之后打印allOutputs 时,我正确地看到第一个索引处的元素具有更新值“1234”。这告诉我 myTest 得到 slice 作为参考。但是后来的"5678" 的append 根本没有被调用者(这里主要)看到,为什么会这样?请记住,原始切片由容量为 100 的数组支持。为什么当切片通过引用传递时,我在 main 中看不到 5678?
换句话说,追加究竟是如何工作的?
import "fmt"
func myTest(array []string) {
array[0] = "1234"
array = append(array, "5678")
}
func main() {
allOutputs := make([]string, 0, 100)
allOutputs = append(allOutput, "abcd")
fmt.Println(allOutputs) // Println1
myTest(allOutputs)
fmt.Println(allOutputs) // Println2
}
实际输出: [1234]
我预计: [1234, 5678]
【问题讨论】:
-
没有“通过引用”,所以我不确定你从哪里得到的。您只是传递切片值,它是一个副本,不会更改原始值。
-
当你传递一个 slice 时,Go 传递一个 slice header 的副本。这就解释了为什么 array[0] = "1234"。您仍然可以访问和提醒底层阵列对象。另一方面,append 创建切片和底层数组的副本,因为
myTest函数没有返回它,所以您看不到main中的更改。当我开始查看 slice 时,我发现 github.com/golang/go/wiki/SliceTricks 非常有用。