go cmd/compile:建议修复“方法具有指针接收器”

pbwdgjma  于 4个月前  发布在  Go
关注(0)|答案(4)|浏览(43)

Go的诊断信息在将非指针传递给接受接口的函数时令人困惑,因为它没有很好地解释问题所在。
示例(https://play.golang.org/p/MXm6RG5fYPy):

package main

import (
	"fmt"
)

type Widget interface {
	DoStuff()
}

type MyWidget struct{}

func (w *MyWidget) DoStuff() {
	fmt.Println("Doing stuff")
}

func doStuffWithWidget(w Widget) {
	w.DoStuff()
}

func main() {
	w := MyWidget{}
	doStuffWithWidget(w)
}

这会产生以下诊断:

./prog.go:23:19: cannot use w (type MyWidget) as type Widget in argument to doStuffWithWidget:
	MyWidget does not implement Widget (DoStuff method has pointer receiver)

...这只说了问题的一半,使得很难看出实际出了什么问题。更好的诊断应该是:

./prog.go:23:19: cannot use w (type MyWidget) as type Widget in argument to doStuffWithWidget:
	MyWidget does not implement Widget (DoStuff method has pointer receiver). Passing &w would work here.
hc2pp10m

hc2pp10m1#

(DoStuff方法有指针接收者)
这一部分清楚地解释了问题所在,因此诊断是完整的。您提议添加一句话,这也建议了一个可能的解决方案,这是两回事。
Go中很少有错误会这样做,因为这会使每个错误消息更加冗长。这种诊断风格在复杂的语言中是有用的,在那里可能根本不明显如何修复一个问题,但我不确定这是情况。根据我的经验,在您已经看到“有指针接收者”错误一两次后,您很快就能学会它的意思(以及如何修复它)。

2nbm6dog

2nbm6dog2#

让我感到困惑的是,方法 doStuffWithWidget 期望的是一个 Widget 而不是一个 *Widget。那么,为什么参数必须用 doStuffWithWidget(&w) 指针发送,而不是 doStuffWithWidget(w)?

ghhaqwfi

ghhaqwfi3#

我认为 (DoStuff method has pointer receiver) 已经提出了一个可能的解决方案,但可能不够明确。
此外,如果参数被替换为指针值,它的类型不一定实现了接口。例如,如果接口是

type Widget interface {
	DoStuff()
        None()
}

,错误信息相同,但 *MyWidget 也未实现 Widget
如果相应的指针类型(在这个例子中是 *MyWidget )没有实现接口,错误可能不应该指 *MyWidget 没有实现的接口方法。
如果相反, *MyWidget 实现了接口,错误应该建议 *MyWidget implements Widget ,如

./prog.go:23:19: cannot use w (type MyWidget) as type Widget in argument to doStuffWithWidget:
	MyWidget does not implement Widget (*MyWidget implements Widget)

所示。

xyhw6mcr

xyhw6mcr4#

无法在doStuffWithWidget函数的参数中使用类型为MyWidget的w(类型为Widget):
MyWidget没有实现Widget接口(DoStuff方法接收到的是指针)
我同意,至少可以说这很令人困惑。更好的消息应该是:
./prog.go:23:19: 无法在doStuffWithWidget函数的参数中使用类型为MyWidget的w(类型为Widget):
MyWidget没有实现Widget接口(DoStuff方法期望接收到指针)

相关问题