gpt4 book ai didi

go - 为什么在仍然可以直接访问的情况下,接口(interface)不使用指针引用实现方法?

转载 作者:IT王子 更新时间:2023-10-29 01:51:02 26 4
gpt4 key购买 nike

我明白接口(interface)没有根据 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: cannot use u (type user) as type modifier in argument to interfaceModify: user does not implement modifier (modify method has pointer receiver)

这解释为:

[…]there is no useful way for a method call to obtain a pointer.

Even in cases where the compiler could take the address of a value to pass to the method, if the method modifies the value the changes will be lost in the caller.

但是,将 interfaceModify(u) 替换为像 u.modify() 这样的直接调用确实有效:编译器获取 u,并将在 Println() 确认时修改其名称属性。

因此,我们能够在那种精确的情况下执行该操作,但不能在界面中进行。我对这种差异的唯一解释是,在 interfaceModify(m modifier) 中,我们会将 u 直接复制到 m,但没办法用于 m 在调用 modify() 时匹配相应的地址。因此,声明 u := &user{"Default Name"} 会将指针(地址)u 复制到 m,并且这就是为什么 m.modify() 是可能的。我说得对吗?

最佳答案

我想你已经明白了。 u.modify() 之所以有效,是因为 go 将其视为 (&u).modify() 的简写。 interfaceModify(&u) 也可以。这是一个 playground,其中包含更多按引用传递与值传递的示例。

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)
}

关于go - 为什么在仍然可以直接访问的情况下,接口(interface)不使用指针引用实现方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40828156/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com