web-dev-qa-db-ja.com

Goは「暗黙の」インターフェースで生産性をどのように改善し、C#の拡張メソッドの概念とどのように比較しますか?

Go言語チュートリアルでは、彼らは explain インターフェースの仕組みを説明します。

Goにはクラスがありません。ただし、構造体型にメソッドを定義できます。 メソッドレシーバーは、funcキーワードとメソッド名の間の独自の引数リストに表示されます。

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

インターフェイスタイプは、一連のメソッドによって定義されます。インターフェイスタイプの値は、これらのメソッドを実装する任意の値を保持できます。

これは、Goでインターフェースを作成する唯一の方法です。 Googleはさらに次のように説明しています。

タイプは、メソッドを実装することによってインターフェースを実装します。意図の明示的な宣言はありません。 interface宣言]。

暗黙的なインターフェイスは、インターフェイスを定義するパッケージから実装パッケージを分離します。どちらも他に依存しません。

また、すべての実装を見つけて新しいインターフェース名でタグ付けする必要がないため、正確なインターフェースの定義を促進します。

これはすべて、疑わしい C#の拡張メソッド のように聞こえますが、Goのメソッドは容赦なく多態性です。それらはそれらを実装する任意のタイプで動作します。

グーグルは、これは急速な発展を促進すると主張しているが、なぜですか? C#の明示的なインターフェイスから離れることによって何かをあきらめますか? C#の拡張メソッドを使用すると、C#でGoインターフェイスが持ついくつかの利点を引き出すことができますか?

21
Robert Harvey

拡張メソッドと暗黙のインターフェースがまったく同じだとは思いません。

最初に目的について話しましょう。

拡張メソッドは、特に、オブジェクトの内部にアクセスすることなく、オブジェクトのメンバーであるかのようにメソッドを使用できるようにする構文糖として存在します。拡張メソッドがなくてもまったく同じことができますが、someObjectYouCantChange.YourMethod()の快適な構文が得られず、YourMethod(someObjectYouCantChange)を呼び出す必要があります。

ただし、暗黙的インターフェースの目的は、変更へのアクセス権がないオブジェクトにインターフェースを実装できるようにすることです。これにより、自分で作成したオブジェクトと内部にアクセスできないオブジェクトの間に多態的な関係を作成できます。

次に、結果について話しましょう。

拡張メソッドには実際には何もありません。これは、.NETがモデルの異なるパースペクティブ(内部、外部、継承者、および近隣からのパースペクティブ)を支援するために使用しようとする冷酷なセキュリティ制約と完全に一致しています。結果は、構文上の快適さです。

暗黙的なインターフェースの影響はいくつかあります。

  • 偶発的なインターフェースの実装。これは、ハッピーアクシデント、または契約の意図を尊重せずに意図していない他の誰かのインターフェースに出会うことによる偶発的なLSP違反である可能性があります。
  • オブジェクトインターフェースをミラーリングするだけで(または、そのメソッドの要件を満たすインターフェースを作成するだけで)、任意のメソッドに任意のオブジェクトのモックを簡単に受け入れさせる機能。
  • 内部で干渉できないオブジェクトに関して、アダプタまたはその他のさまざまな類似パターンをより簡単に作成する機能。
  • インターフェースの実装を遅らせ、実際の実装に手を加える必要なく後で実装します。実際に別の実装者を作成したいときにだけ実装します。
12
Jimmy Hoffa