范围引用而不是值

Epi*_*lle 66 pointers reference go

我看到该范围返回键和值的"副本".该范围是否有办法返回该项目的地址?例

package main

import "fmt"

type MyType struct {
    field string
}

func main() {
    var array [10]MyType

    for _, e := range array {
        e.field = "foo"
    }

    for _, e := range array {
        fmt.Println(e.field)
        fmt.Println("--")
    }
}
Run Code Online (Sandbox Code Playgroud)

http://play.golang.org/p/AFOGG9NGpx

这里"字段"没有被修改,因为范围发送字段的副本,我是否必须使用索引或是否有任何其他方法来修改值?

谢谢阅读.

Mus*_*hin 94

简短而直接的答案:不,使用数组索引而不是值

所以上面的代码变成:

package main

import "fmt"

type MyType struct {
    field string
}

func main() {
    var array [10]MyType

    for idx, _ := range array {
        array[idx].field = "foo"
    }

    for _, e := range array {
        fmt.Println(e.field)
        fmt.Println("--")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 当然,如果你反复访问`array [idx]`你可以选择在for循环的顶部有`e:=&array [idx]`然后使用`e.field1`,`e.field2`等等与OP更接近的类似可能需要(只有两行而不是一行). (27认同)
  • 您可以删除`,_`完全 - `for idx:= range array` (9认同)
  • 想知道为什么 Go 确实将引用复制到范围的第二个值。复制那里的值几乎没有用,不是吗? (3认同)

小智 14

结合@Dave C@Sam Toliman的评论

package main

import "fmt"

type MyType struct {
    field string
}

func main() {
    var array [10]MyType

    for idx := range array {
        e := &array[idx]
        e.field = "foo"
    }

    for _, e := range array {
        fmt.Println(e.field)
        fmt.Println("--")
    }
}
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/knKfziB1nce


Gra*_*sky 10

Gorange只支持按值赋值。没有&range,因为它解决的问题太微不足道了。

可以达到预期的效果如下:

for i := range array {
    e := &array[i]
    e.field = "foo"
}
Run Code Online (Sandbox Code Playgroud)