英文:
Why do methods on pointers work when the pointer is a variable, but not otherwise?
问题
当运行以下代码时:
package main
import (
"fmt"
)
type Bar struct {
name string
}
func (foo Bar) testFunc() {
fmt.Println(foo.name)
}
func doTest(pointer *Bar) {
pointer.testFunc() // 在指针上运行`testFunc`(尽管它期望的是`Bar`类型的值,而不是`*Bar`类型)
}
func main() {
var baz Bar = Bar{
name: "Johnny Appleseed",
}
doTest(&baz) // 将`baz`的指针发送给`doTest()`
}
输出结果为:Johnny Appleseed
。我本以为在指针上调用testFunc()
会出错。
之后,我尝试将doTest(&baz)
替换为&baz.testFunc()
。然后我收到了错误信息:
tmp/sandbox667065035/main.go:24: baz.testFunc() used as value
为什么我只有在直接调用baz.testFunc()
而不是通过另一个函数调用时才会出错?调用doTest(&baz)
和&baz.testFunc()
不是做了完全相同的事情吗?因为doTest(pointer *Bar)
只是调用了pointer.testFunc()
。
Playground 2 (&baz.testFunc()
)
英文:
When running the following code:
package main
import (
"fmt"
)
type Bar struct {
name string
}
func (foo Bar) testFunc() {
fmt.Println(foo.name)
}
func doTest(pointer *Bar) {
pointer.testFunc() // run `testFunc` on the pointer (even though it expects a value of type `Bar`, not `*Bar`)
}
func main() {
var baz Bar = Bar{
name: "Johnny Appleseed",
}
doTest(&baz) // send a pointer of `baz` to `doTest()`
}
The output reads: Johnny Appleseed
. I would have thought I would have encountered an error for calling testFunc()
on a pointer.
After that, I tried switching out doTest(&baz)
for &baz.testFunc()
. Then I received the error:
tmp/sandbox667065035/main.go:24: baz.testFunc() used as value
Why do I only get the error when calling baz.testFunc()
directly instead of through another function? Wouldn't calling doTest(&baz)
and &baz.testFunc()
do the exact same thing, as doTest(pointer *Bar)
simply calls pointer.testFunc()
?
答案1
得分: 2
这是因为自动解引用method values。
与选择器一样,对于使用指针的值接收器的非接口方法的引用,将自动解引用该指针:pt.Mv 等同于 (*pt).Mv。
对于第二行,你出现了这个错误,是因为你对 testFunc 的结果取了地址,而 testFunc 并没有返回任何值。
你尝试做的是:
(&baz).testFunc()
这样可以正常工作。
英文:
It's because of automatic derefencing of method values
> As with selectors, a reference to a non-interface method with a value receiver using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv.
For the second line, you have this error because you take the address of the result of testFunc which doesn't return any value.
What you tried to do is the following:
(&baz).testFunc()
which works as expected
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论