【问题标题】:Methods dispatch using interface in Go在 Go 中使用接口调度方法
【发布时间】:2020-04-22 02:08:45
【问题描述】:

如果我们使用接口、静态(编译时)或动态(运行时),Go 中的方法实际上是如何分派的。让我们考虑这段代码:

package main

import "fmt"

type ICat interface {
    Meow()
    Walk()
    Run()
}
func NewCat(name string) ICat {
    return &cat{
        name:name,
    }
}
type cat struct {
    name string
}
func (c *cat) Meow() {
    fmt.Print("Meowwwwwwwww")
}
func (c *cat) Walk() {
    fmt.Print("Walk")
}
func (c *cat) Run() {
    fmt.Print("Run")
}


type IAnimal interface{
    DoSound()
}
type animal struct {
    cat ICat
}
func New() IAnimal {
    return &animal{
        cat:NewCat("bobby"),
    }
}
func (a *animal) DoSound() {
    a.cat.Meow()
}


func main() {
    i := New()
    i.DoSound()
}

去游乐场:https://play.golang.org/p/RzipDT6FAC9

这些接口中定义的方法实际上是如何分派的?我使用这种开发风格来实现接口隔离以及数据和行为之间的关注点分离。我的另一个担心是性能。有人说它是在编译时静态分派的,而另一些人说它是在运行时动态分派的。

【问题讨论】:

  • 语言在这里不做任何保证。任何编译器都可能做它认为最合适的事情,甚至在星期一做不同的事情。
  • “有人说它是在编译时静态分派的” 在一般情况下这是不可能的,因为the compiler can't always know the dynamic type(这就是它被称为动态的原因)。在编译时甚至可能不存在接口的实现。

标签: go interface dispatch


【解决方案1】:

我们无法在编译时知道接口值的动态类型,通过接口调用必须使用dynamic dispatch。编译器必须生成代码以从类型描述符中获取方法的地址,而不是直接调用,然后对该地址进行间接调用。

【讨论】:

    猜你喜欢
    • 2014-04-08
    • 2011-09-20
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 2023-04-03
    • 2012-10-28
    • 2017-07-07
    相关资源
    最近更新 更多