LoginSignup
0
0

More than 1 year has passed since last update.

GoのError()とString()の優先順位

Last updated at Posted at 2022-08-16

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.goprintArgが呼び出されている。
image.png

こちらで、type switchを用いて引数の型別に処理を行う。
image.png
(省略)
image.png

当然、MyTypeはcaseにないので、defaultまで落ちてくる。(一瞬、MyTypeの根底はstringなのでcase stringに引っかかるのかと思ったが、MyTypeはstring型の値を保持しているだけで、MyTypeはstring型ではないので、引っかからない)

image.png

defaultでは、handleMethodsを呼び出している。

途中省略してるが、errorとStringerの分岐はここにあった。case errorが先に書かれているので、当然Error()とString()両方持っているタイプはfmtではerrorとして扱われる。

image.png

やはり両方のメソッドを持っているパターンは思い浮かばないが(というかError()と別の文字列表現がわざわざほしい、みたいなケースなので相当まれか

まあ、中身が少しわかったのでよしとします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0