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.
4条答案
按热度按时间hc2pp10m1#
(DoStuff方法有指针接收者)
这一部分清楚地解释了问题所在,因此诊断是完整的。您提议添加一句话,这也建议了一个可能的解决方案,这是两回事。
Go中很少有错误会这样做,因为这会使每个错误消息更加冗长。这种诊断风格在复杂的语言中是有用的,在那里可能根本不明显如何修复一个问题,但我不确定这是情况。根据我的经验,在您已经看到“有指针接收者”错误一两次后,您很快就能学会它的意思(以及如何修复它)。
2nbm6dog2#
让我感到困惑的是,方法
doStuffWithWidget
期望的是一个Widget
而不是一个*Widget
。那么,为什么参数必须用doStuffWithWidget(&w)
指针发送,而不是doStuffWithWidget(w)
?ghhaqwfi3#
我认为
(DoStuff method has pointer receiver)
已经提出了一个可能的解决方案,但可能不够明确。此外,如果参数被替换为指针值,它的类型不一定实现了接口。例如,如果接口是
,错误信息相同,但
*MyWidget
也未实现Widget
。如果相应的指针类型(在这个例子中是
*MyWidget
)没有实现接口,错误可能不应该指*MyWidget
没有实现的接口方法。如果相反,
*MyWidget
实现了接口,错误应该建议*MyWidget implements Widget
,如所示。
xyhw6mcr4#
无法在doStuffWithWidget函数的参数中使用类型为MyWidget的w(类型为Widget):
MyWidget没有实现Widget接口(DoStuff方法接收到的是指针)
我同意,至少可以说这很令人困惑。更好的消息应该是:
./prog.go:23:19: 无法在doStuffWithWidget函数的参数中使用类型为MyWidget的w(类型为Widget):
MyWidget没有实现Widget接口(DoStuff方法期望接收到指针)