main声明一个名称为allOutputs
的切片(我相信它是一个字符串切片,而不是字符串数组),长度为零,容量为100。然后,它会附加一个值为“ abcd”的字符串,并调用myTest函数,该函数会将array [0]更新为“ 1234”,然后执行一个附加值为“ 5678”的事情。
在allOutputs
调用后打印myTest
时,我正确地看到第一个索引处的元素的更新值为“ 1234”。这告诉我myTest得到了切片作为参考。但是调用者(主要在此处)根本看不到append
中后来的"5678"
,为什么这样呢?还记得原始切片由容量为100的数组支持吗?为什么切片通过引用传递时主视图中看不到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]
答案 0 :(得分:0)
append
的工作原理与您认为的完全一样!
如您在this playground中所见,如果不将append
数组作为参数传递给allOutputs
,则myTest
函数将按预期工作。
您怀疑,如果超出了原始阵列的容量,append
可能返回一个新阵列。在您的示例中,未修改了myTest
中的数组大小,但是,它是allOutputs
的副本,保持不变。
最好把一个数组想成一个字符串。这是可变的内存块。作为参数传递时,将复制整个块。
您的假设是正确的,因为数组allOutputs
已预先分配了100个元素,因此对append
的调用无需更改array
。
如果您写的是 this ,您会看到预期的结果。
allOutputs := make([]string, 0, 100)
allOutputs = append(allOutputs, "abcd")
fmt.Println(allOutputs) // Println1
allOutputs[0] = "1234"
allOutputs = append(allOutputs, "5678")
fmt.Println(allOutputs) // Println2
一个不错的解决方案是:
type myStrings []string
func (m *mystring) myTest() {
// Do something
}
如果您声明自己的类型,则可以定义一个方法,该方法可以在不显式使用&运算符的情况下对数组进行变异。