インターフェースは、メソッド名だけを定義した型です。
定義の違う構造体は、違う型になります。同じ型の要素だけで構成される配列やスライスの要素に、違う構造体を指定することできません。しかし、インターフェース(interface)を使うと、違う構造体を、同じ型として扱うことができ、配列やスライスの要素にすることができます。
package main
import "math/rand"
import "time"
type display interface {
show()
}
type greet struct {}
type score struct {}
type janken struct {}
func (g greet) show() {
names := []string{"John.", "Bob.", "Jack."}
println("I am", names[rand.Intn(3)],"Nice to meet you.")
}
func (s score) show() {
println("Score is", rand.Intn(101))
}
func (j janken) show() {
hands := []string{"rock.", "paper.", "scissors."}
println("You are", hands[rand.Intn(3)])
}
func main() {
rand.Seed(time.Now().Unix())
displays := []display{greet{}, score{}, janken{}}
for _, display := range displays {
display.show()
}
}
I am John. Nice to meet you.
Score is 66
You are scissors.
type display interface {
show()
}
インターフェースの定義は、type キーワード、任意のインターフェース名、interface キーワードと記述して、{ と } の間に、メソッド名を記述します。メソッド名は、幾つでも記述できます。
func (g greet) show() {
上記のように記述すると、greet 構造体は、display インターフェースの show メソッドと関連づけられます。インターフェースのメソッドと関連づけた構造体は、そのインターフェースの型として扱えるようになります。このようにインターフェースのメソッドと関連づけすることを、そのインターフェースを採用するとも言います。
インターフェースを採用する構造体では、インターフェースの一部のメソッドだけを採用することはできます。しかし、インターフェースで定義されたすべてのメソッドを採用しなければ、そのインターフェースの型として扱うことはできません。