java - go和Java接口之间的区别是什么?

  显示原文与译文双语对照的内容
115 5

最近我被问到一个问题,那就是Golang和Java之间有什么不同的界面?

我知道存在一些'句法糖级别'差异,我感兴趣的是底层什么,比如Golang和Java如何实现接口?最大的区别是什么哪个更有效?为什么?

谁可以发布博客链接或者关于这个主题的源代码?源代码更好。

谢谢。

时间:原作者:0个回答

69 5

go数据结构:由 Russ Cox提供的接口

interfaces—static,在编译时检查,请求时动态
of使用象 python 这样的纯动态语言,但是仍然使编译器捕获一个具有读取方法的对象的显式错误。
接口不限于 static 检查,尽管。你可以动态检查某个接口值是否具有其他方法。

接口值
使用方法的语言通常属于以下两个阵营之一:为所有方法调用表调用静态( 在 C++ 和Java中),或者在每个调用( 就像Smalltalk及其许多 imitators 。JavaScript和 python 所包含的一样) 中做一个方法查找并添加高效缓存。位于两者之间的一半:它有方法表,但在运行时计算。我不知道围棋是使用这种技术的第一种语言,但它肯定不是一种常见的语言。
接口值表示为两个单词对,给出指向存储在接口中的类型的信息的指针和指向关联数据的指针。将b 分配给Stringer类型的接口值 both interface值的两个字。

接口值的第一个字指向我调用的接口表或者 itable ( pronounced表;在运行时源中) 。itable从有关涉及的类型的一些元数据开始,然后变成函数指针的列表。注意,itable对应于接口类型,而不是动态类型。
在接口值中的第二个字指向实际数据,在本例中是一个副本。

转换类型转换的动态意味着编译器或者链接器对所有可以能的itables进行重新排序是不合理的:( 。接口类型,具体类型) 对太多,而且大多数都不需要。编译器为每个具体类型( 如二进制或者int或者 func ( 映射 [int] 字符串) ) 生成一个类型描述结构。在其他元数据中,类型描述结构包含由该类型实现的方法的列表。同样,编译器为每个接口类型生成( 不同) 类型描述结构;它也包含方法列表。在type类型表的具体方法中,接口运行时通过查找表的接口方法中列出的每个方法来计算 itable 。运行时在生成后缓存 itable,因此只需计算一次这里对应项。

方法查找性能
Smalltalk和许多动态系统,它们在每次调用方法时执行方法查找。对于速度,许多实现在每个调用站点都使用一个简单的条目缓存,通常在指令流本身中。在多线程程序中,必须小心管理这些缓存,因为多个线程可以同时位于同一个调用站点。即使避免了比赛,缓存也将成为内存争用的来源。

因为in具有 static 键入的提示,所以它可以以将查找从调用站点移回到该点。

如何执行接口调度工作

接口变量的方法调度与vtable调度相同。
第一次,混凝土类型击入一个接口类型,它将生成一个指向的哈希表项。相同类型的第二个和后续赋值将执行更便宜的哈希查找以查找 vtable 。但是,方法调度本身总是等价于vtable查找。

规范:接口类型

有关详细信息,请参阅::接口 {}的含义是什么?

下面是Go中两个有趣的接口用例:Golang中为什么需要接口

错误类型是接口类型:如何比较Golang错误对象

计算 4个不同形状的面积:圆,正方形,rectangle 和三角形:
中解释类型声明

这里你不需要做任何特别类似于Java关键字 implements的事情来实现接口。

下面是代码( 在上试试go游乐场 ):

package main
import"fmt"
type Work struct {
 Name string
}
func (t Work) String() string {
 return"Stringer called."
}
func main() {
 w := Work{"Hi"}
 fmt.Println(w)
}

输出:

Stringer called.

说明:类型 Stringer,并查看源:

type Stringer interface {
 String() string
}

Stringer由任何具有字符串方法的值实现,该方法定义了值的"本机"格式。字符串方法用于打印作为操作数传递给任何接受字符串或者未格式化的打印机( 如打印)的值的值。

另请参阅:

为什么不能将 *Struct 分配给 *Interface?
嵌入匿名接口的结构的含义
嵌入接口插件
Golang: 当你拥有多个inheritence组件时,接口是什么

原作者:
...