接口和指针接收器 [英] Interfaces and pointer receivers

查看:142
本文介绍了接口和指针接收器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手gopher,正在努力使我的头脑转向指针接收器和接口.

I am newbie gopher and trying to get my head around the pointer receivers and interfaces.

type Foo interface {
    foo()
}
type Bar struct {}
func (b *Bar) foo() {}

基于上述定义.

--- Allowed ---------
b := Bar{}
b.foo()

--- Not allowed ----- 

var foo Foo = Bar{}

获取编译器错误: 不能在分配中使用Bar文字(Bar类型)作为Foo类型: Bar不实现Foo(foo方法具有指针接收器)

Get compiler error: cannot use Bar literal (type Bar) as type Foo in assignment: Bar does not implement Foo (foo method has pointer receiver)

我知道在第一种情况下,编译器正在代表我们进行一些指针转换和取消引用.为什么在第二种情况下它不做同样的事情?

I understand that compiler is doing some pointer conversion and de-referencing on our behalf in the first scenario. Why doesn't it do the same thing in the second scenario ?

推荐答案

简短的回答var foo Foo = Bar{}不起作用,因为存储在接口中的具体值不可寻址.

Short answer var foo Foo = Bar{} is not working because the concrete value stored in an interface is not addressable.

长版

请阅读 https://github.com/golang/go/wiki/MethodSets

在任何 已经是一个指针或可以获取其地址的指针.称呼是合法的 值方法,可以是任何值或值可以是 取消引用.

It is legal to call a pointer-valued method on anything that is already a pointer or whose address can be taken. It is legal to call a value method on anything which is a value or whose value can be dereferenced.

关于上述说明,您的代码

With respect to the above explanation, your code

b := Bar{}
b.foo()

之所以起作用,是因为b是可寻址的.

works because b is addressable.

接口中存储的具体值不可寻址. 因此,当您在接口上调用方法时,它必须具有 相同的接收器类型,或者必须与接收器直接区别 具体类型:可以使用以下方法调用指针和值接收器方法 指针和值分别,正如您所期望的那样.价值接受者 可以使用指针值来调用方法,因为它们可以 首先取消引用.指针接收器方法不能用调用 值,但是,因为存储在接口内的值没有 地址.在为接口分配值时,编译器确保 实际上所有可能的接口方法都可以在该方法上调用 值,因此尝试进行不正确的分配将失败 编译.

The concrete value stored in an interface is not addressable. Therefore, when you call a method on an interface, it must either have an identical receiver type or it must be directly discernible from the concrete type: pointer- and value-receiver methods can be called with pointers and values respectively, as you would expect. Value-receiver methods can be called with pointer values because they can be dereferenced first. Pointer-receiver methods cannot be called with values, however, because the value stored inside an interface has no address. When assigning a value to an interface, the compiler ensures that all possible interface methods can actually be called on that value, and thus trying to make an improper assignment will fail on compilation.

根据上述说明,接口中存储的具体值不可寻址,因此代码

According to the above explanation the concrete value stored in an interface is not addressable and hence the code,

var foo Foo = Bar{}

将不起作用,因为接口中存储的具体值(在本例中为Bar{})不可寻址.

will not work because the concrete value stored in an interface, in this case Bar{}, is not addressable.

这篇关于接口和指针接收器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆