-3

main 声明了一个带有名称的切片allOutputs(我相信它是一个字符串切片,而不是字符串数组),长度为零,容量为 100。然后它附加一个值为“abcd”的字符串并调用 myTest 函数,该函数将数组 [0] 更新为“1234”,然后附加一个值为“5678”。

allOutputs当我在通话后打印myTest时,我正确地看到第一个索引处的元素的更新值为“1234”。这告诉我 myTest 得到 slice 作为参考。但是调用者(这里主要)根本看不到后者append,为什么会这样?"5678"请记住,原始切片由容量为 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]

4

1 回答 1

0

append完全按照您的想法工作!

正如您在这个 playground中看到的append那样,如果您不将allOutputs数组作为参数传递给myTest.

正如您所怀疑的,如果超出原始数组的容量,append 可能会返回一个新数组。在您的示例中,数组大小myTest未修改但是,它是allOutputs保持不变的副本。

最好将数组想象成字符串。它是一个可变的内存块。当作为参数传递时,整个块被复制。

您的假设是正确的,因为数组allOutputs预先分配了 100 个元素,因此调用append不需要更改array

如果你写了这个,你会看到你预期的结果。

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
   }

如果您声明自己的类型,那么您可以定义一个可以改变数组的方法,而无需显式使用 & 运算符。

于 2019-05-20T02:53:05.303 回答