gpt4 book ai didi

pointers - 在 Go 中将指针分配给接口(interface)时与隐式指针取消引用混淆

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

刚开始接触Go,正在研究它的接口(interface)特性。

代码如下:

package main

import (
"fmt"
"reflect"
)

type Integer int

func (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 = 1

var b LessAdder = &a

func main() {
fmt.Println(reflect.TypeOf(b))
fmt.Println(b.Less(2))
b.Add(a)
fmt.Println(a)

}

它会输出以下内容:

*main.Integer
true
2

嗯,这很好用。

重点是:var b LessAdder = &a 是如何工作的。指针自动解引用是就在这里发生,还是在 b 调用成员方法时发生?

输出 *main.Integer 告诉我们 b 是一个指向类型 Integer 的指针,因此它是第二种情况。

然后棘手的事情来了:当我将 fmt.Pringln(*b) 添加到代码中时,编译器出现错误:

 demo/demo1
./demo1.go:31: invalid indirect of b (type LessAdder)

这让我很困惑。 由于 b 是指向 Integer 的指针类型,因此取消引用它应该可行。但为什么不呢?

最佳答案

你的最后一句话:

"Since b is a pointer type to Integer, then dereferencing it should work."

停在那里。 b 不是指针类型的变量,因此你不能 dereference

interface type的变量它是一对值和类型 (value,type),将 &a 作为值,将 *Integer 作为类型(博客文章 The Laws of Reflection,部分The representation of an interface ).

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

var ip *Integer

这是一种接口(interface)类型:

var intf LessAdder

当你这样做时:

var b LessAdder = &a

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

现在当你调用 b.Less(2) 时,由于 Less() 有一个值接收者,指针将被取消引用,指向值的副本将作为方法 Less() 的值接收者制作和使用/传递。

fmt.Println(reflect.TypeOf(b)) 不会说谎,但它会打印bdynamic 类型。 b的动态类型确实是*Integer,但是bstatic类型是LessAdder 静态类型决定了你可以用一个值做什么,以及允许对它做什么运算符或方法。

关于pointers - 在 Go 中将指针分配给接口(interface)时与隐式指针取消引用混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31065917/

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