2016-10-08 5 views
1

最近、私はGolangとJavaの違いは何ですか、という質問がありましたインタフェースについてGoとJavaの違いは何ですか?

「構文上の糖レベル」の違いがあることは知っていますが、私が興味を持っているのはGolangとJavaがどのようにインターフェイスを実装しているのかのように、最も大きな違いは何ですか?どれが効率的ですか?どうして?

誰でもこのトピックに関するブログのリンクやソースコードを投稿できますか?ソースコードが優れています。

ありがとうございました。 Pythonのような純粋に 動的言語でのラス・コックスによって

答えて

2

Go Data Structures: Interfaces

ゴーのインタフェース静的、動的な、コンパイル時にチェック
ため を尋ねられたときゴーのインターフェイスは、あなたがあなたのようなダックタイピングを使用してみましょうだろうが、コンパイラがReadメソッドを持つオブジェクトが と予想されていた場合、または 引数が間違ったReadメソッドを呼び出す場合のように、intを渡すような間違いがあります。
インターフェイスはスタティックチェックに制限されません。特定のインターフェイス値に追加の メソッドがあるかどうかを確認するには、 を動的にチェックします。

インタフェース方法に
言語は、典型的には二つの陣営のいずれかに分類値:すべての方法のため テーブルを準備する(C++やJavaのように)静的呼び出し、又は同様 に各コールでメソッドルックアップを(DO Smalltalkとその多くの模倣者、 JavaScriptとPythonが含まれています)、効率的な呼び出しを行うためには、空のキャッシングを追加してください。 Goは2つの間にあります。メソッドテーブル がありますが、実行時に計算されます。このテクニックを使用するために、Goが最初の 言語かどうかはわかりませんが、確かに一般的ではありません。
インターフェイス値は、インターフェイスに格納されているタイプに関する情報と、対応するデータの へのポインタへのポインタ を与える2語のペアとして表されます。 のインタフェース値にbを割り当てるStringerは、インタフェース値の両方のワードを設定します。

インターフェイス値の最初の単語は、 インターフェイステーブルまたはitable(i-tableと発音されます;ランタイム ソース)と呼ばれます。 itableは、タイプ に関するメタデータから始まり、関数ポインタのリストになります。 itableは、インターフェイスタイプに対応し、動的タイプには対応しません。
インターフェイス値の2番目の単語は、実際のデータを指しています。 この例では、bのコピーです。

ゴーのダイナミック型変換は、それが可能なすべてのitablesを事前計算する コンパイラやリンカのための合理的ではないことを意味する:あまりにも 多くの(インターフェイスタイプ、具体的なタイプ)のペア、そして最も必要とされることはありませんがあります。 代わりに、コンパイラは、Binaryまたはintまたはfunc(map [int] string)のような具象型の各 の型記述構造体を生成します。他の メタデータの中で、型記述構造には、その型によって実装された メソッドのリストが含まれています。同様に、コンパイラは、 のように各インターフェイスタイプに対して (異なる)タイプの記述構造を生成します。メソッドリストも含まれています。インタフェースランタイム は、具体的な型のメソッドテーブルの 型のメソッドテーブルにリストされている各メソッドを検索することによって、itableを計算します。ランタイム は生成後にitableをキャッシュするので、この対応は が1回だけ計算される必要があります。

メソッドのルックアップパフォーマンス
のSmalltalkと、それは メソッド検索にメソッドが呼び出されるたびに実行に続いてきた多くの動的システム。速度を高めるために、多くの の実装では、各呼び出しサイトで単純な1エントリキャッシュが使用されます。多くの場合、命令ストリーム自体には があります。マルチスレッドプログラムでは、複数のスレッドが同時に同じ呼び出しサイト にある可能性があるため、これらの キャッシュを慎重に管理する必要があります。レースが終了しても が回避されても、キャッシュはメモリ競合の原因になります。

Goには、動的な メソッドのルックアップに対応するための静的なタイピングのヒントがあるため、コールサイトから値がインターフェイスに格納された時点の にルックアップを戻すことができます。インタフェース変数に


How does Go interface dispatch work?

メソッドディスパッチはvtableの ディスパッチと同じです。
初めてコンクリート型がインタフェース型にヒットすると、vtableを指す ハッシュテーブルエントリが作成されます。 2番目以降の 同じタイプの割り当ては、より安価なハッシュ検索を行い、 vtableを検索します。しかし、メソッドディスパッチ自体は常にvtableルックアップと同等の です。


スペック:詳細についてInterface types

は、以下を参照してください。ここGo: What's the meaning of interface{}?


、囲碁のインターフェイスの2興味深いユースケース: Why are interfaces needed in Golang?


エラータイプがインタフェース型である:あなたがいない
Explain Type Assertions in Go


ここに行く中:How to compare Golang error objects


4つの異なる形状の計算エリア:サークル、正方形、長方形と三角形インターフェイスを実装するために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. 

スペック:ここ

は、コード(The Go Playground上でそれを試してみてください)でtype Stringerは、とsourceを参照してください。

type Stringer interface { 
     String() string 
} 

Stringerは、Stringメソッドを持つ任意の値で実装されます。 は、その値の「ネイティブ」形式を定義します。 Stringメソッドは、 文字列、またはPrintなどの書式なしのプリンタを受け入れる形式にオペランドとして渡された値を出力するために を使用します。


も参照してください:

Why can't I assign a *Struct to an *Interface?
Meaning of a struct with embedded anonymous interface?
Embedded Interface
Golang: what's the point of interfaces when you have multiple inheritence

+0

おかげで仲間が、私はこの差は構文糖のレベルにあると思いますが、私が知りたいですプログラミング言語/コンパイラ/ランタイムレベルでの違い。メソッドテーブル、メソッド検索、ランタイム型チェックなどのようなもの。 – fding

+0

@fding新しい編集を参照してください。私はこれが役立つことを願っています –

関連する問題