我用结构体A
编写了指针接收器方法,并创建了两个函数
- 期望
A
类型切片作为参数, - 期望
map[int]A
类型映射作为参数。
都遍历a的值和调用a的pinter receiver方法,但是当它调用in 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中,map值是不可寻址的。这意味着你不能得到一个指向映射值(aa[k]
)的指针,因此你不能在这个值上调用一个带有指针接收器的方法。
解决方法如下:
for k := range aa {
e := aa[k]
e.Add(i)
aa[k] = e
}
首先感谢go playground,它真的很有帮助。
你的方法使用一个指针接收器,和映射,是用来存储一个键对象,如前所述,映射在go是不可寻址的(为什么不允许'不允许获取映射值的地址?),所以你需要做的是:在地图上做一个范围,1°值是关键,第二个是值所以你的结构被保存在内存中作为一个Key: struct。
一个选项是将映射声明为:
map[int]*A
因此,当您从映射中查看值时,您可以访问指针方法。
for _,value := range aa {
value.Add(i)
}
操场在这里:https://play.golang.org/p/eVA8ujrdcO4
另一种解决方案是将map[i]A保留为map[i]A,只是在for范围内:将值返回给它的键,如下所示:
for k,value := range aa {
value.Add(i)
aa[k]=value
}
操场在这里:https://play.golang.org/p/k-Qr8oYpL6j