为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中为接口分配指针时与隐式指针取消引用混淆

在 Go 中为接口分配指针时与隐式指针取消引用混淆

Go
jeck猫 2021-10-18 14:30:28
我是 Go 的新手,我正在研究它的界面功能。这是代码:package mainimport (        "fmt"        "reflect")type Integer intfunc (a Integer) Less(b Integer) bool {        return a < b}func (a *Integer) Add(b Integer) {        *a += b}type LessAdder interface {        Less(b Integer) bool        Add(b Integer)}var a Integer = 1var b LessAdder = &afunc main() {        fmt.Println(reflect.TypeOf(b))        fmt.Println(b.Less(2))        b.Add(a)        fmt.Println(a)}它将输出以下内容:*main.Integertrue2嗯,这很好用。重点是:如何var b LessAdder = &a运作。指针自动取消引用是在这里发生,还是在 b 调用成员方法时发生?输出*main.Integer告诉我们 b 是指向 type 的指针Integer,因此是第二种情况。然后棘手的事情来了:当我添加fmt.Pringln(*b)到代码中时,编译器出现错误: demo/demo1./demo1.go:31: invalid indirect of b (type LessAdder)这让我很困惑。由于b是指向 的指针类型Integer,因此取消引用它应该可以工作。但为什么不呢?
查看完整描述

2 回答

?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

你的最后一句话:

“由于b是指向 的指针类型Integer,因此取消引用它应该可以工作。”

停在那儿。b不是指针类型的变量,因此,你不能解引用它。

它是接口类型的变量,示意性地是一对值和类型 (value,type),&a作为值和*Integer作为类型(博客文章反射定律,接口的表示部分)。

这是一个指针类型变量的声明*Integer

var ip *Integer

这是一种接口类型:

var intf LessAdder

当你这样做时:

var b LessAdder = &a

发生的情况是LessAdder自动/隐式创建了一个接口值(类型),它将保存值&a(和类型*Integer)。这是一个有效的操作,因为的类型&a(这是*Integer)实现接口LessAdder:该方法集的*Integer是接口的一个超集LessAdder(在这种情况下,它们是相等的,一个接口类型的方法集为其接口)。

现在,当您调用 时b.Less(2),由于Less()具有值接收器,指针将被取消引用,并且将制作指向值的副本并作为方法的值接收器使用/传递Less()

fmt.Println(reflect.TypeOf(b))不说谎,但它会打印出动态的类型b。的动态类型b确实是*Integer,但静态类型bLessAdder,而静态类型决定了您可以对值做什么以及允许使用哪些运算符或方法。


查看完整回答
反对 回复 2021-10-18
?
森栏

TA贡献1810条经验 获得超5个赞

LessAdder被声明为具有方法Less和的接口Add。由于Add是用 的接收者声明的*Integer,所以 a*Integer可以是 a LessAdder;一个Integer不能。当你这样做时var b LessAdder = &a,它是指向a存储在接口中的指针b

自动间接发生在对 的调用时b.Less(2),因为方法 on*Integer和方法 on 都Integer有助于 的方法集*Integer

您不能使用,*b因为虽然b 包含*Integer,但的静态类型是LessAdder,而不是*Integer。撇开接口的表示不谈,LessAdder不是指针类型,并且*b如果允许,则根本没有可表达的类型。

您可以使用一个类型断言访问b作为Integer *一次; b.(*Integer)是 type 的表达式*Integer,并且*b.(*Integer)Integer. 如果 in 的值毕竟b不是 a *Integer,那么这两种方法都会导致运行时恐慌。


查看完整回答
反对 回复 2021-10-18
  • 2 回答
  • 0 关注
  • 205 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信