【问题标题】:Does declaring an array size explicitly determine pass by value vs reference?声明数组大小是否明确确定按值传递还是按引用传递?
【发布时间】:2020-11-08 07:54:37
【问题描述】:

以不改变其父数组的数组副本为例:

    a1 := [5]string{"English", "Japanese", "Spanish", "French", "Hindi"}
    a2 := a1 
    fmt.Println("a1 = ", a1) //[English Japanese Spanish French Hindi]
    fmt.Println("a2 = ", a2) //[English Japanese Spanish French Hindi]
    a2[1] = "German"
    fmt.Println("now a2 = ", a2) // [English German Spanish French Hindi]
    fmt.Println("and a1 = ", a1) // [English Japanese Spanish French Hindi]

毫不奇怪,a2 是副本,而不是参考。更改副本不应该更改另一个副本,它们保存在不同的地址。

现在看看如果我们不向 a1 声明大小会发生什么:

    a1 := []string{"English", "Japanese", "Spanish", "French", "Hindi"} // <--difference here
    a2 := a1
    fmt.Println("a1 = ", a1) //[English Japanese Spanish French Hindi]
    fmt.Println("a2 = ", a2) //[English Japanese Spanish French Hindi]
    a2[1] = "German"
    fmt.Println("now a2 = ", a2) // [English German Spanish French Hindi]
    fmt.Println("and a1 = ", a1) // [English German Spanish French Hindi]

当 a2 改变时两者都改变​​?!所以,如果你没有为数组声明一个大小,然后将它分配给某个东西,突然它是一个引用?为什么 a2 := a1 的行为会完全不同,具体取决于另一个变量的声明方式?我很困惑哈哈。

【问题讨论】:

  • 当你不声明大小时,它是一个slice,而不是一个数组,虽然是一个相关的东西,但它是完全不同的。
  • 该死的,这很微妙
  • tour.golang.org/moretypes/6和下一页。
  • Go 总是通过值传递,从不通过引用。

标签: arrays go pass-by-reference


【解决方案1】:

我强烈建议阅读 Go 博客文章 Arrays, slices and strings - 然后再阅读一遍 - 它包含许多其他微妙的副作用。

它将显示幕后发生的事情以及切片类型的表示方式:

sliceHeader{
    Length:        0,
    Capacity:      0,
    ZerothElement: nil, // points to a fixed size array
}

因此变异操作如何影响多个切片值。

最后一句话:

数组有自己的位置——它们很好地代表了一个 例如转换矩阵——但它们在 Go 中最常见的用途 是为切片保存存储空间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-28
    • 2017-11-14
    相关资源
    最近更新 更多