本文へスキップ
BecomeCoder

Goコース · 第5章 構造体・メソッド・インターフェース · レッスン19

インターフェース ― 「できること」で型をまとめる

ブラウザで完結

導入

インターフェース は「このメソッドを持っている型なら何でもいい」という約束です。具体的な型が何であるかを問わず、「〜できるもの」として扱えます。

説明

package main

import "fmt"

// String() を持つ型なら何でも Stringer として扱える
type Stringer interface {
    String() string
}

type Dog struct{ Name string }
type Cat struct{ Name string }

func (d Dog) String() string { return d.Name + "(犬)" }
func (c Cat) String() string { return c.Name + "(猫)" }

func introduce(s Stringer) {
    fmt.Println("これは " + s.String())
}

func main() {
    introduce(Dog{Name: "ポチ"}) // これは ポチ(犬)
    introduce(Cat{Name: "タマ"}) // これは タマ(猫)
}
  • type Stringer interface { String() string } … 「String() string メソッドを持つ」という条件を表す型。
  • DogCatString() を持つので、どちらも自動的に Stringer として扱えます(「implements」と宣言する必要はありません)。
  • introduce は具体的な型を知らず、「String() できるもの」だけを受け取ります。

このように「宣言なしで、メソッドさえ揃えば適合する」仕組みを ダックタイピング と呼びます。犬と猫を同じ関数で扱えるのが、インターフェースの力です。

やってみよう

新しく type Bird struct{ Name string } と、その String() メソッドを足せば、introduce(Bird{...}) もそのまま動きます。introduce 側を1行も変えずに対応できるのがインターフェースの狙いです。

実際に動かしてみよう

下のエディタにGoを書いて「実行」を押すと、学習用シミュレータが fmt の出力を表示します(本物のGoコンパイラではなく、教材の範囲を再現した軽量エンジンです)。スライス・マップ・構造体・インターフェース・goroutine/channel なども動きます。本文の例を書き換えて動かしてみましょう(並行処理の実行順は決定的に再現しているため、本物のインターリーブとは異なる場合があります)。

Go — ブラウザ内で実行(学習用シミュレータ)

Goの教材サブセットを動かす学習用シミュレータを読み込みます(本物のGoコンパイラではなく、動きを再現した軽量な自作エンジンです)。
スクロールして表示された時点でも自動で読み込まれます。