什么';Go和Java在接口方面的区别是什么?

什么';Go和Java在接口方面的区别是什么?,java,go,interface,Java,Go,Interface,最近有人问我一个问题,Golang和Java在接口方面有什么不同 我知道有一些“语法糖级”的差异,我感兴趣的是地下的任何东西,比如Golang和Java如何实现接口?最大的区别是什么?哪一个更有效?为什么? 有人能在博客上发布关于这个主题的链接或源代码吗?源代码更好 谢谢。罗斯·考克斯 Go的接口静态,编译时检查,请求时动态 对于 Go的接口让您可以像在纯键盘中一样使用duck类型 像Python这样的动态语言,但仍然有明显的编译器缺陷 错误,比如在读取对象的位置传递int 应为,或者类似于使用

最近有人问我一个问题,Golang和Java在接口方面有什么不同

我知道有一些“语法糖级”的差异,我感兴趣的是地下的任何东西,比如Golang和Java如何实现接口?最大的区别是什么?哪一个更有效?为什么?

有人能在博客上发布关于这个主题的链接或源代码吗?源代码更好

谢谢。

罗斯·考克斯

Go的接口静态,编译时检查,请求时动态 对于
Go的接口让您可以像在纯键盘中一样使用duck类型 像Python这样的动态语言,但仍然有明显的编译器缺陷 错误,比如在读取对象的位置传递int 应为,或者类似于使用错误的 参数。
不过,接口并不局限于静态检查。你可以查一下 动态地确定特定接口值是否具有附加值 方法

接口值
具有方法的语言通常分为两大阵营之一:prepare 所有方法调用的表静态(如C++和java),或 每次调用时的方法查找(如Smalltalk及其许多模仿者, (包括JavaScript和Python),并添加了奇特的缓存 打电话效率高Go位于两者之间:它有方法表 但是在运行时计算它们。我不知道Go是否是第一个 语言使用这种技术,但它肯定不是一种常见的技术。
接口值表示为给出指针的两个字对 有关存储在接口中的类型的信息和指向 关联的数据。将b分配给类型为的接口值 Stringer设置接口值的两个字

接口值中的第一个单词指向我所说的 接口表或itable(发音为i-table;在运行时 资料来源)。itable以一些关于类型的元数据开始 包含,然后成为函数指针列表。请注意 itable对应的是接口类型,而不是动态类型。
接口值中的第二个字指向实际数据,即 本案为b

Go的动态类型转换意味着它对于 预计算所有可能的ITable的编译器或链接器:太多了 许多(接口类型、具体类型)对,大多数都不需要。 相反,编译器会为每个类型生成一个类型描述结构 具体类型,如二进制、int或func(映射[int]字符串)。除其他外 元数据,类型描述结构包含 由该类型实现的方法。类似地,编译器生成 (不同)每个接口类型的类型描述结构,如 纵梁;它也包含一个方法列表。接口运行时 通过查找接口中列出的每个方法来计算itable 混凝土类型的方法表中类型的方法表。运行时 在生成itable后缓存它,以便 只需计算一次

方法查找性能
Smalltalk和许多紧随其后的动态系统执行了 每次调用方法时进行方法查找。对于速度,许多 实现通常在每个调用站点使用一个简单的单条目缓存 在指令流本身中。在多线程程序中,这些 缓存必须小心管理,因为可能同时存在多个线程 同时访问同一个呼叫站点。即使比赛已经结束 如果避免,缓存最终将成为内存争用的来源

因为Go有静态类型的提示,可以与动态类型一起使用 方法查找,它可以将查找从调用站点移回 值存储在接口中的点


接口变量上的方法分派与vtable相同 调度。
当具体类型第一次命中接口类型时,它会构建一个 指向vtable的哈希表项。第二次及其后 同一类型的赋值将对 找到vtable。但是方法分派本身总是 相当于vtable查找


规格:

有关更多详细信息,请参阅:


下面是Go中两个有趣的接口用例:


错误类型是一种接口类型:


计算四种不同形状的面积:圆形、方形、矩形和三角形:


在Go中,您不需要做任何特殊的事情,比如Java关键字
实现
来实现接口,在Go中,您的类型只需要有具有正确签名的方法就足够了

以下是代码(请试穿):

输出:

Stringer called.

等级库:,请参见:

Stringer由任何具有String方法的值实现,该方法 定义该值的“本机”格式。使用字符串方法 将作为操作数传递的值打印为接受 字符串或到未格式化的打印机,如打印


另见:





谢谢兄弟,但我认为这种差异是在语法层面上的,我想知道编程语言/编译器/运行时层面上的差异。类似方法表、方法查找、运行时类型检查等…@fding请参阅新编辑。我希望这有帮助。接口不需要通过代码显式实现。它们可以嵌入到其他接口和结构中。看见
Stringer called.
type Stringer interface {
        String() string
}