dprxj1995 2019-05-19 16:53
浏览 80

传递切片作为参考,以反映调用者的更改[重复]

This question already has an answer here:

main declares a slice with name allOutputs (i believe its a slice of strings, not an array of strings) with zero length and 100 capacity. Then it appends a string with value "abcd" and calls myTest function which updates the array[0] with "1234" and then does an append with value "5678".

When i printed allOutputs after myTest call, i correctly see the element at the first index has an updated value of "1234". This tells me that myTest got slice as reference. But the later append of "5678" is not seen by the caller (main here) at all why its so? Remember the original slice is backed by an array with a capacity of 100. Why can't i see 5678 in main when the slice is passed by a reference?

In other words, how exactly the append works?

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
}

ACTUAL OUTPUT: [1234]

I EXPECTED: [1234, 5678]

</div>
  • 写回答

1条回答 默认 最新

  • dongxiang3648 2019-05-20 02:53
    关注

    append works exactly as you think it does!

    As you can see in this playground, the append function works as you're expecting if you don't pass the allOutputs array as a parameter to myTest.

    As you suspected, append may return a new array if the capacity of the original array is exceeded. In your example, the array size in myTest is not modified, however, it is a copy of allOutputs which remains unchanged.

    It's best to think of an array like a string. It's a mutable block of memory. When passed as a parameter, the whole block is copied.

    Your assumption that, because the array allOutputs is pre-allocated with 100 elements the call to append won't need to change array, is correct.

    If you'd written this, you would have seen the results you expected.

    allOutputs := make([]string, 0, 100)
    allOutputs = append(allOutputs, "abcd")
    fmt.Println(allOutputs) // Println1
    allOutputs[0] = "1234"
    allOutputs = append(allOutputs, "5678")
    fmt.Println(allOutputs) // Println2
    

    One nice solution to this is:

       type myStrings []string
    
       func (m *mystring) myTest() {
          // Do something
       }
    

    If you declare your own type, then you can define a method that can mutate the array without explicitly using the & operator.

    评论

报告相同问题?

悬赏问题

  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 ubuntu系统下挂载磁盘上执行./提示权限不够
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型