首页 文章

为什么不能用指针接收器实现接口

提问于
浏览
49

我很困惑为什么这不能编译:

不可能的类型断言:Faz没有实现Foo(Bar方法有指针接收器)

如果我为Faz.Bar制作Faz.Bar的接收器而不是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`
}

2 回答

  • 50

    因为它是 *Faz 而不是 Faz .

    func main() {
        foo := New().(*Faz)
        log.Println(foo)
    }
    
  • 4

    我认为这个问题的答案需要采用更加回顾性的语法方法,以及如何通过软件工程实现它 . (借口过度简化)


    首先是 types 的快速闪回?
    它们只是顶部带有编译器逻辑的内存块 . arraystring 的不同之处在于编译器允许我们对这些内存块做什么 . (深入思考,你可能会开始意识到 strongly typeddynamically typed 语言之间的真正区别 . )

    接下来你需要意识到每个说法指针都是他们自己的类型 .
    *variable 是与 variable 不同的内存块(也称为类型) . 只是编译器始终假定 *variable 的内容始终是声明右侧类型的内存块的地址以及它所强加的其他限制/功能 .

    然后让我们回顾一下界面是什么 .
    伪科学定义:任何一等公民属于特定类型的一组要求 . 转换为软件工程 - 与 Contract ( interface )中描述的具有相同内存结构(回想起structure packing)的任何内存(类型)块都可以与 Contract 提及的类型名称一起传递 .


    现在,当你说时,你可能会开始意识到这一点

    func (f *Faz) Bar() string 是持有函数的 f 的内存块,其中 f 的类型是指向 Faz 的指针

    哪个地区

    func (f Faz) Bar() stringf 的内存块,其中 f 的类型是 Faz

    因此,当您说 *Faz 类型的变量满足合约时,您如何假设 Faz 类型的变量将符合代码中的接口类型?选择满足您的 Contract ,只有该类型可以在您的代码中采用接口类型 .

相关问题