Go 接口:静态与动态绑定

Go 使用动态和静态绑定。根据我的理解,如果您需要使用类型断言,那么它是动态的。我想验证我的假设。


type Xer interface { 

  X()

}


type XYer interface {

  Xer

  Y()

}


type Foo struct{}

func (Foo) X() { println("Foo#X()") }

func (Foo) Y() { println("Foo#Y()") }

假设:


foo := Foo{}


// static: Foo -> XYer

var xy XYer = foo


// static: XYer -> Xer

var x Xer = xy


// static: Xer -> interface{}

var empty interface{} = x


// dynamic: interface{} -> XYer

xy2 := empty.(XYer)


// dynamic: XYer -> Foo

foo2 := xy2.(Foo)

因此,当从type A->转换时interface B,如果A满足B则不需要断言,并且可以在编译时生成 itable。如果您在不需要断言的情况下使用断言呢?


var x Xer = Foo{}

empty := x.(interface{})

在这种情况下会发生什么?如果有人可以为我澄清这一点,那就太好了。


大话西游666
浏览 175回答 2
2回答

明月笑刀无情

我不知道什么是接口的静态绑定或接口的动态绑定。语言规范从未提及此类术语。让我假设您的意思是在编译时进行类型检查,在运行时进行类型检查。有了这个假设,你所有的例子都是,AFAICS,正确的。它归结为一个简单的模式(相关语言规范部分的精简版本):所有赋值都在编译时进行类型检查。所有类型断言 ( .(T)) 在运行时都经过类型检查。这也回答了“在这种情况下会发生什么?” .也就是说,编译器可以自由地优化可以在编译时证明类型已知且赋值兼容的情况。但这只是一个不能依赖的实现细节 - 因为其他符合规范的实现可能不是这种情况。实际上 gc 编译器有 (IINM) 这样的优化,甚至在相反的意义上。它可以说“不可能的类型断言”,它可以在编译时证明类型断言将失败。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go