【发布时间】:2017-04-11 05:20:03
【问题描述】:
我知道接口没有按照 Go 规范和常见问题实现带有指针引用的方法,因为 T 和 *T 有不同的方法集 (https://golang.org/doc/faq#guarantee_satisfies_interface)。
所以,这不起作用:
package main
import (
"fmt"
)
type user struct {
name string
}
type modifier interface {
modify()
}
func (u *user) modify() {
u.name = "My name"
}
func interfaceModify(m modifier) {
m.modify()
}
func main() {
u := user{"Default Name"}
interfaceModify(u)
fmt.Println(u.name)
}
然后返回:
./main.go:26: 不能在 interfaceModify 的参数中使用 u(类型用户)作为类型修饰符: 用户没有实现修饰符(修改方法有指针接收器)
这解释为:
[…]方法调用没有获得指针的有用方法。
即使在编译器可以将值的地址传递给方法的情况下,如果方法修改了值,更改也会在调用者中丢失。
但是,将 interfaceModify(u) 替换为像 u.modify() 这样的直接调用确实有效:编译器获取 u 的地址,并会在 Println() 确认时修改其 name 属性。
因此,我们能够在这种精确的情况下执行该操作,但不能在界面一中执行。我对这种差异的唯一解释是,在interfaceModify(m modifier) 中,我们将直接将 u 复制到 m,而 m 没有办法调用modify()时匹配对应的地址。
因此,声明u := &user{"Default Name"} 会将指针(so 地址)u 复制到m,这就是为什么m.modify() 是可能的。
我说的对吗?
【问题讨论】:
标签: go