gpt4 book ai didi

pointers - 满足接口(interface)的 Go 结构方法类型

转载 作者:IT王子 更新时间:2023-10-29 00:50:00 25 4
gpt4 key购买 nike

给定以下 Go 代码示例:

package main

import "fmt"

type greeter interface {
hello()
goodbye()
}

type tourGuide struct {
name string
}

func (t tourGuide) hello() {
fmt.Println("Hello", t.name)
}

func (t *tourGuide) goodbye() {
fmt.Println("Goodbye", t.name)
}

func main() {
var t1 tourGuide = tourGuide{"James"}
t1.hello() // Hello James
t1.goodbye() // Goodbye James (same as (&t1).goodbye())

var t2 *tourGuide = &tourGuide{"Smith"}
t2.hello() // Hello Smith
t2.goodbye() // Goodbye Smith (same as (*t2).hello())

// illegal: t1 is not assignable to g1 (why?)
// var g1 greeter = t1

var g2 greeter = t2
g2.hello() // Hello Smith
g2.goodbye() // Goodbye Smith
}

我可以使用类型为 tourGuide t1 的变量或指向 tourGuide t2 的指针来调用结构 tourGuide 的两个方法>。换句话说,我可以使用 T*T 类型的变量调用带有 T 接收器的方法。同样,我可以使用 T 类型的变量调用带有 *T 接收器的方法(如果 Taddressable )或 *T。我知道编译器会处理此处的差异(请参阅我在代码中的注释)。

但是,当我们实现接口(interface)时,情况会发生变化。在上面的代码中,greeter 接口(interface)类型的变量可以从指向 tourGuide 的指针赋值,但不能从 tourGuide 赋值。

谁能告诉我为什么会这样?为什么我可以调用 t1.hello()t1.goodbye() 但不知何故 t1 对接口(interface) 来说还不够迎宾员?

最佳答案

如果一个方法有一个指针接收者,那么只有一个指针值可以作为接收者值。因此,要在某个值上调用此方法,该值本身必须是一个指针,或者必须可以获取其地址(用作接收者)。

例如,如果您有一个变量,它是 addressable因此可以获取它的地址并将其用作接收者。规范允许您这样做,这是自动发生的。

包装在接口(interface)中的值是不可寻址的。创建接口(interface)值时,将复制包装在接口(interface)中的值。因此无法获取其地址。从理论上讲,您可以允许获取副本的地址,但这将是(甚至)比它提供的好处更困惑的根源,因为地址将指向副本,而带有指针接收器的方法只能修改副本而不是原来的。

查看此答案,其中详细说明/证明在创建接口(interface)值时复制了值:How can a slice contain itself?

关于pointers - 满足接口(interface)的 Go 结构方法类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41015114/

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