为什么不能用指针接收器来实现接口
我很困惑,为什么这不能编译:
不可能的types断言:Faz没有实现Foo(Bar方法有指针接收器)
如果我使接收器Faz.Bar Faz值而不是一个Faz指针,然后它编译好,但我认为总是有更好的指针接收器,所以值不被复制?
package main import ( "log" ) func main() { foo := New().(Faz) log.Println(foo) } type Foo interface { Bar() string } func New() Foo { return &Faz{} } type Faz struct { } func (f *Faz) Bar() string { return `Bar` }
因为它是*Faz
而不是Faz
。
func main() { foo := New().(*Faz) log.Println(foo) }
我认为这个问题的答案需要对语法有更多的回顾,如何通过软件工程来实现。 (不要过分简化)
首先是什么types
的快速闪回?
它们只是带有编译器逻辑的内存块。 使string
与string
不同的是编译器允许我们使用这些内存块。 (更深入地思考,你可能会开始意识到strongly typed
和dynamically typed
语言之间的真正区别。)
现在接下来你需要认识到指针是他们自己的types。
*variable
是一个不同的内存块(又名types)比variable
。 只是编译器总是假设*variable
内容总是要成为声明右侧的内存块的地址,以及它所施加的其他限制/function。
那么让我们回顾一下界面是什么。
伪科学定义 :任何一类公民具有特定types的一套要求。 翻译成软件工程 – 与契约( interface
)中描述的相关的内存结构(回想结构打包 )的任何内存块(types)都可以像合同中提到的types名一样传递。
现在你可能会开始意识到,当你说
func (f *Faz) Bar() string
是f
的持有一个函数的内存块,其中f
的types是指向Faz
的指针
哪里有地方
func (f Faz) Bar() string
是f
的内存块,其中f
的types是Faz
所以当你说一个*Faz
types的variables满足一个契约时,那么你怎么能假定一个Faz
types的variables将被限定为代码中的接口types呢? select满足您的合同,只有这种types可以承担代码中的接口types。