🐷

Go interface の備忘録

2021/05/18に公開

初め.

普段はPythonをメインにコードを書いているが,最近はGolangを勉強し始めました.最初はA Tour of Goを読みながら勉強しました.そこで,Interfaceのところ苦戦し,特にExercise:Stringersでかなり苦戦しましたので,備忘録を残しておきます.

Exercise

まず正しく作動するプログラムはこちらです.

exercise-stringer.go
package main

import "fmt"

type IPAddr [4]byte

// TODO: Add a "String() string" method to IPAddr.
func (id IPAddr) String() string {
	return fmt.Sprintf("%d.%d.%d.%d",id[0], id[1], id[2], id[3])
}

func main() {
	hosts := map[string]IPAddr{
		"loopback":  {127, 0, 0, 1},
		"googleDNS": {8, 8, 8, 8},
	}
	for name, ip := range hosts {
		fmt.Printf("%v: %v\n", name, ip) //question1
	}
}

こちらのプログラムで思った疑問点はいくつあります.

疑問1

question: //question1の行でなぜ,一度もString()メソッドを実行していないのに,func (id IPAddr) String() stringで定義したメソッドの返り値が出力されているのか.
answer: fmt.Printf()では,Stringerインターフェイスならば,優先的にString()メソッドでreturnされている文字列を出力する仕様となっているようです.

疑問2

question: hosts構造体は一度もStringerインターフェイスとして扱うように宣言していないのに,なぜインターフェイスになっているのか.
ansewer 定義されているメソッドを全て実装した時点で,勝手にインターフェイスとしてみなされるので,自分で宣言する必要がないようです.

type Stringer interface {
    String() string
}

今回ではString()を実装すれば,自動的にStringerインターフェイスとして扱われるます.

最後に

かなり苦戦しましたが,これで納得できました.初めの投稿で間違っている部分があるかもしてませんが,ご指摘をいただける嬉しいです.

Discussion