Go に関する 興味深いブログ記事を見つけました。
インターフェイスの概念を理解しようとしていますが、ブログ投稿のコード フラグメントから理解するのは非常に難しく、言語仕様からはほぼ不可能です。
動作中のプログラムでの Go のインターフェイスの簡単な例を指摘できる人はいますか?
チュートリアル「Goのインターフェイス-パート2:適応性のある進化的な設計の支援」(2012年1月、Sathish VJから)では、Goのインターフェイスの主な利点について明確に説明しています。
Goのインターフェースは、JavaまたはC#インターフェースのバリアントではなく、はるかに優れています。
それらは、大規模なプログラミングと適応性のある進化的な設計の鍵です。
バスの異なる視点(インターフェース)については、同じ記事から次の例を参照してください。
package main
import "fmt"
//Go Step 1: Define your data structures
type Bus struct {
l, b, h int
rows, seatsPerRow int
}
//Go Step 2: Define a real world abstraction that could use the data we structure we have
type Cuboider interface {
CubicVolume() int
}
//Go Step 3: Implement methods to work on data
func (bus Bus) CubicVolume() int {
return bus.l * bus.b * bus.h
}
//Go step - repeat 2 & 3 for any other interfaces
type PublicTransporter interface {
PassengerCapacity() int
}
func (bus Bus) PassengerCapacity() int {
return bus.rows * bus.seatsPerRow
}
func main() {
b := Bus{
l:10, b:6, h:3,
rows:10, seatsPerRow:5}
fmt.Println("Cubic volume of bus:", b.CubicVolume())
fmt.Println("Maximum number of passengers:", b.PassengerCapacity())
}
データ中心のようです。最初にデータを定義し、作業を進めながらインターフェースの抽象化を構築します。
ここでの階層は、明示的に指定せずに「途中で」構築されたものです。型に関連付けられたメソッドシグネチャによっては、特定のインターフェイスを実装していると理解されます。時間の経過とともに、バスのプロジェクト要件の一部が変更されたと仮定しましょう。現在、各乗客は少なくとも一定の最小量の立方体体積を持つ必要があるという新しい法律があります。
バスはPersonalSpaceLaw
、すでに実装されている他のインターフェイスとは異なる、という新しいインターフェイスに準拠する必要があります。
//new requirement that the Bus must be compatible with
type PersonalSpaceLaw interface {
IsCompliantWithLaw() bool
}
func (b Bus) IsCompliantWithLaw() bool {
return (b.l * b.b * b.h) / (b.rows * b.seatsPerRow) >= 3
}
機能は、コアクラスまたはコア階層を変更せずに拡張されました。この実装は、はるかにクリーンで簡単に拡張でき、プロジェクトの要件の変化するニーズに合わせて拡張できます。
これがGoPlaygroundで動作する完全なプログラムです
この記事は、Goのインターフェースの生産性に関するスレッドからのJohnAsmuthの引用で終わります。
「ある種の型階層を事前に設計し、それを2、3回再配置してから終了する必要がないのは事実です。
それを正しく行うのが簡単であるという事実すらありません。それ
は、心配する必要はなく、実際のアルゴリズムに取り掛かることができます。」
これは進行中の学習演習であり、確かに良いスタイルの悪い例ですが、ここに行きます( spec )。
さらに、より風変わりな例として、匿名データを操作する関数 (この場合は「三項演算」関数) を構築するための interface{} の使用に関して、go-nuts メーリング リストに投稿しました。
package main
import "fmt";
func Tern(exp bool, a interface{}, b interface{}) (interface{}) {
if exp { return a }
return b
}
func main() {
a := 7; b := 1;
result := Tern(a > b, a, b);
fmt.Printf("%d\n", result);
}
package main
type Stringer interface {
String() string
}
type pie int
type pizza string
func (p pie) String() string{
return "pie"
}
func (p pizza) String() string{
return "pizza"
}
func main(){
var a pie
var b pizza
fmt.Println(a,b) //fmt.Println() will look for Stringers and call their String() method.
}
ウィキペディアではダックタイピングについて説明しており、Go での例があります。 http://en.wikipedia.org/wiki/Duck_typing
Go におけるインターフェースの基本的な概念は、インターフェースを定義したメソッドを実装するオブジェクトは、そのインターフェースの一部になることができるということです。
最良の例は Writer インターフェースです。Rob Pike は、Google Tech Talk ( http://www.youtube.com/watch?v=rKnDgT73v8s )でのイントロ スピーチでこの例を示しています。彼の説明については、スピーチの 33:25 までスクロールしてください。