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


21

Go言語のチュートリアルでは、インターフェイスの仕組みについて説明しています。

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宣言]。

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

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

これはすべて、Goのメソッドが容赦なく多態的であることを除いて、C#の拡張メソッドに似ています。それらは、それらを実装する任意のタイプで動作します。

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



1
これらのGoインターフェイスは、C#拡張メソッドよりも、C ++テンプレートでできることのように聞こえます。C#には「メソッドAとBを実装する型」のようなものはありませんが、C ++テンプレートを使用してそれを行うことができます。
svick


「暗黙的なインターフェース」は単なるカモタイピングではありませんか?
アロングラネネク

「「暗黙的なインターフェース」は単なるカモタイピングではありませんか?」Goのインターフェイスは、構造型付けの例です。非常に類似したコンセプト。
mortdeus

回答:


12

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

まず、目的について話しましょう。

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

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

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

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

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

  • 偶発的なインターフェースの実装。これは幸せな事故、または契約の意図を尊重しない間に意図しない他の誰かのインターフェースに会うことによる偶発的なLSP違反です。
  • オブジェクトインターフェイスをミラーリングするだけで(またはメソッドの要件を満たすインターフェイスを作成するだけで)、特定のオブジェクトのモックをメソッドが簡単に受け入れるようにする機能。
  • アダプターや他のさまざまな類似のパターンを、内部で邪魔できないオブジェクトに関してより簡単に作成する機能。
  • インターフェースの実装を遅らせ、後で実際の実装を変更せずに実装します。実際に別の実装者を作成したい場合にのみ実装します。

Linqの拡張メソッドの有用性は、主に、メソッドの実装をインターフェイス(特にIEnumerableおよび)に移植する能力によってもたらされますIQueryablestaticユーティリティクラスのメソッドを使用してこれを偽造することはできますが、不器用です。
ロバートハーベイ

@RobertHarveyインターフェースにメソッドを置くと主張することは必ずしも正確ではありません。インターフェースの実際のメソッドと拡張メソッドの違いに注意してください。インターフェースのメソッドは、そのインターフェースを実装するクラス内に実装されます。どの拡張方法よりも多くのアクセスが可能です。繰り返しますが、視点の変更であり、クラス内に実装されたコードには、外部と比較して特別な視点が与えられます。
ジミーホファ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.