チュートリアルの翻訳、8回目です。
前回までの訳はチュートリアル[日本語訳]にまとめてありますのでごらんください。


 ソート

Go言語のインタフェースはポリモーフィズムを実現します。
ポリモーフィズムにより、オブジェクトのふるまいと実際の処理を完全に分離できるので、同一インタフェースを実装していても型が異なるオブジェクトを、ひとつの変数を使って(代入しなおす必要はありますが)アクセスすることができます。

下の簡単なソートアルゴリズムの例をみてください。このファイルはprogs/sort.goにあります。

13    func Sort(data Interface) {
14        for i := 1; i < data.Len(); i++ {
15            for j := i; j > 0 && data.Less(j, j-1); j-- {
16                data.Swap(j, j-1);
17            }
18        }
19    }

Sortに渡されるInterfaceに必要なのは3つのメソッドだけです。 

07    type Interface interface {
08        Len() int;
09        Less(i, j int) bool;
10        Swap(i, j int);
11    }

Sort関数には、このLen,Less,Swapメソッドを実装さえしていればどんな型でも渡すことができます。

sortパッケージには、整数値や文字列の配列をソートするのに必要なメソッドが用意されています。
下は、int型の配列をソートするコードです。 

33    type IntArray []int

35    func (p IntArray) Len() int            { return len(p); }
36    func (p IntArray) Less(i, j int) bool  { return p[i] < p[j]; }
37    func (p IntArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

構造体ではない型に対しメソッドを定義していることがお分かりいただけるでしょうか。
どんな型であっても、それが定義されたパッケージ内であればメソッドを定義することができます。

これをテストするためのルーチンです。これはprogs/sortmain.goファイルにあります。
ここではコードを省略するため、sortパッケージのIsSortedメソッドを使って実際にソートされているか確認しています。

12    func ints() {
13        data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586};
14        a := sort.IntArray(data);
15        sort.Sort(a);
16        if !sort.IsSorted(a) {
17            panic()
18        }
19    }

新しい型をソート可能にするには、このように3つのメソッドを実装するだけです。

30    type day struct {
31        num        int;
32        shortName  string;
33        longName   string;
34    }

36    type dayArray struct {
37        data []*day;
38    }

40    func (p *dayArray) Len() int            { return len(p.data); }
41    func (p *dayArray) Less(i, j int) bool  { return p.data[i].num < p.data[j].num; }
42    func (p *dayArray) Swap(i, j int)       { p.data[i], p.data[j] = p.data[j], p.data[i]; }