Go 1.18
Go初心者です。
A Tour Of Go
Stringer~Errorsをやっていた。https://go-tour-jp.appspot.com/methods/19
Goのプログラムは、エラーの状態を error 値で表現します。
error 型は fmt.Stringer に似た組み込みのインタフェースです:type error interface { Error() string }
( fmt.Stringer と同様に、 fmt パッケージは、変数を文字列で出力する際に error インタフェースを確認します。 )
つまり、fmt.Print(f)をしたときに、f
のメソッドString()
と、メソッドError()
を探しに行き、その文字列を(Printなら改行なしで)プリントする。
では、以下のように、String()とError()両方をもつインタフェースをfmtが呼び出したときにはどうなるか。
package main
import "fmt"
type MyType string
func (h MyType) String() string {
return "ストリング"
}
func (h MyType) Error() string {
return "エラー"
}
func main() {
f := MyType("fuga")
fmt.Print(f)
}
これは、
エラー
が出力される。
fmt
の中を見てみよう。どうやってString()やError()を探しにいっているのか。
fmt.Print(f)をデバグすると以下のように、fmt/print.go
のprintArg
が呼び出されている。
こちらで、type switch
を用いて引数の型別に処理を行う。
(省略)
当然、MyTypeはcaseにないので、defaultまで落ちてくる。(一瞬、MyTypeの根底はstringなのでcase string
に引っかかるのかと思ったが、MyTypeはstring型の値を保持しているだけで、MyTypeはstring型ではないので、引っかからない)
default
では、handleMethods
を呼び出している。
途中省略してるが、errorとStringerの分岐はここにあった。case errorが先に書かれているので、当然Error()とString()両方持っているタイプはfmtではerrorとして扱われる。
やはり両方のメソッドを持っているパターンは思い浮かばないが(というかError()と別の文字列表現がわざわざほしい、みたいなケースなので相当まれか
まあ、中身が少しわかったのでよしとします。