从 Slice 元素中的 struct 值调用指针接收器方法和 Map 元素 [duplicate] 之间的区别

Difference Between Calling Pointer Receiver Method From Struct Value in Slice element and Map element [duplicate]

提问人:nipuna 提问时间:8/6/2021 最后编辑:nipuna 更新时间:8/6/2021 访问量:238

问:

我用结构体编写了指针接收器方法并创建了两个函数A

  1. 期望类型切片作为参数和A
  2. 期望类型 Map 作为参数。map[int]A

两者都遍历 A 的值并调用 pinter 接收器方法。但是当它在 map 中调用时,下面提到了一个编译错误。切片元素值和映射值均为main.A

./main.go:28:8: cannot call pointer method on aa[k]
./main.go:28:8: cannot take the address of aa[k]

带有编译错误的代码被注释,代码如下。

package main

type A struct {
    I int
}

func (a *A) Add(i int)  {
    a.I += i
}

func main()  {
    aa2 := []A{{I:5}}
    testSlice(aa2, 10)
    //aa1 := map[int]A{
    //  5: {I:5},
    //}
    //testMap(aa1, 10)
}

func testSlice(aa []A, i int)  {
    for k := range aa {
        aa[k].Add(i)
    }
}

//func testMap(aa map[int]A, i int)  {
//  for k := range aa {
//      aa[k].Add(i)
//  }
//}

未注释的代码在这里

请帮我澄清一下,为什么会发生这个编译错误?

字典 Go 指针 切片

评论

5赞 8/6/2021
简短的回答是映射值是不可寻址的。
2赞 8/6/2021
与其试图引用规范,我认为这个链接真的很好 utcc.utoronto.ca/~cks/space/blog/programming/......
2赞 8/6/2021
至于内部发生的事情,这应该有助于 stackoverflow.com/questions/38168329/......

答:

0赞 aureliar 8/6/2021 #1

在 go 中,映射值不可寻址。这意味着您无法获取指向映射值 () 的指针,因此您不能调用具有指针接收器的方法。aa[k]

解决方法如下:

for k := range aa {
        e := aa[k]
        e.Add(i)
        aa[k] = e
    }
0赞 João Vitor Astori Saletti 8/6/2021 #2

首先感谢 go playground,它真的很有帮助。

好吧,你的方法使用指针接收器,而 maps 用于存储键对象,正如 aureliar 所说,Go 中的 maps 是不可寻址的(为什么 Go 不允许获取 map 值的地址? ),所以你需要做的是这样的: 在地图上做一个范围,1°值是关键,第二个是值 因此,您的结构体作为 Key : Struct 保存在内存中。

一种选择是将该映射声明为:

map[int]*A 

因此,当您从映射中查看值时,您可以访问指针方法。

for _,value := range aa {
        value.Add(i)
}

这里是游乐场:https://play.golang.org/p/eVA8ujrdcO4

其他解决方案可以将 map 保留为 map[i]A,只是在 for 范围内:将值返回给其键,如下所示:

for k,value := range aa {
        value.Add(i)
        aa[k]=value
    } 

这里是游乐场:https://play.golang.org/p/k-Qr8oYpL6j