我确实了解接口不会按照Go规范和FAQ来实现带有指针引用的方法,因为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)
}
Run Code Online (Sandbox Code Playgroud)
并返回:
./main.go:26:无法在接口修改的参数中使用u(类型用户)作为类型修饰符:用户未实现修饰符(modify方法具有指针接收器)
解释为:
[…]没有有效的方法调用来获取指针。
即使在编译器可以将值的地址传递给方法的情况下,如果方法修改了该值,则更改也将在调用方中丢失。
但是,用interfaceModify(u)类似的直接调用替换u.modify()确实可行:编译器采用u的地址,并在Println()确认时修改其name属性。
因此,我们能够在那种精确的情况下执行该操作,但不能在接口之一中进行。我对这种区别的唯一解释是,在中interfaceModify(m modifier),我们将把u直接复制到m,并且在调用时m无法匹配相应的地址modify()。因此,声明u := &user{"Default Name"}将因此将指针(so地址)u复制到m,这m.modify()就是可能的原因。我对么?
小智 5
我想你已经明白了。u.modify()之所以有效,是因为go将其视为简写(&u).modify()。interfaceModify(&u)也可以。这是一个操场,其中有更多通过引用与价值传递的示例。
https://play.golang.org/p/HCMtcFAhLe
package main
import (
"fmt"
)
type user struct {
name string
}
type userPointer struct {
user
}
func (up *userPointer) modify() {
up.name = "My name"
}
type modifier interface {
modify()
}
func (u user) modify() {
u.name = "My name"
}
func interfaceModify(m modifier) {
m.modify()
}
func main() {
u := user{"Default Name"}
u.modify()
fmt.Println(u.name)
interfaceModify(u)
fmt.Println(u.name)
up := userPointer{user{"Default Name"}}
interfaceModify(&up)
fmt.Println(up.name)
// short hand version
up.name = "Default Name"
up.modify()
fmt.Println(up.name)
// long hand version https://golang.org/ref/spec#Calls
up.name = "Default Name"
(&up).modify()
fmt.Println(up.name)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
134 次 |
| 最近记录: |