モジュールのレッスン (4/5)
ストリンガーインターフェイス
fmt.Stringer は、おそらくすべての中で最もよく使用される標準インターフェイスです。
Go の標準ライブラリ。それは力の完璧なデモンストレーションです
小さなインターフェイスの。
意味
type Stringer interface {
String() string
}一枚のサイン。 String() string を定義する型はすべて次の条件を満たします。
それ。そして、fmt はこのインターフェイスを認識します。値を渡すと、
fmt.Print*、Stringer を実装する場合は、String() の結果
デフォルトの表現の代わりに使用されます。
例
type Point struct{ X, Y int }
func (p Point) String() string {
return fmt.Sprintf("(%d,%d)", p.X, p.Y)
}
fmt.Println(Point{1, 2}) // (1,2)
fmt.Printf("%v %s\n", Point{3, 4}, Point{5, 6})
// (3,4) (5,6)%v、%s、Println では、同じ値がカスタム書式設定で印刷されます。
Sprint、log など。すべて 1 つのメソッドを定義するだけです。
意味があるとき
- ドメインをモデル化するタイプ (ID、コード、座標、列挙)。
- 人間が判読できる表現でのエラー (
errorに関する次のレッスンを参照)。 - 頻繁にログを記録し、固定フォーマットが必要なタイプ。
すべてに当てはまるわけではありません: 型が単純でデフォルトの表現の場合 大丈夫です、ノイズを加えないでください。
列挙型: iota との共通パターン
type Status int
const (
OK Status = iota
WARN
ERR
)
func (s Status) String() string {
switch s {
case OK: return "OK"
case WARN: return "WARN"
case ERR: return "ERR"
default: return "UNKNOWN"
}
}
fmt.Println(OK, WARN, ERR) // OK WARN ERRString() がない場合、fmt.Println(OK) は 0 を出力します。 String() を使用すると、
シンボリック名を出力します。 stringer
ツールはこのパターンを自動的に生成します。
無限再帰に注意してください
type T int
func (t T) String() string {
return fmt.Sprintf("%d", int(t)) // OK: cast to int breaks the recursion
}ポインタ受信機のストリンガー
String() にポインター レシーバーがある場合、*T のみが Stringer を満たします。
fmt.Println(t) (値) を使用して、Go は T のメソッド セットを調べます。
見つからないため、デフォルトの形式が使用されます。これを回避するには、値を指定します。
通常、receiver は String() に使用されます (これは「ビュー」ですが、そうではありません)
何かを変更します)。
試してみてください
Point に String() を実装して、(X,Y) を返すようにします。
ヒントを表示
`fmt.Sprintf` を使用してフィールドをフォーマットします。
3 回の試行後に解決策が利用可能になります
型 Status (int) に String() を実装します: 0 → 'OK'、1 → 'WARN'、それ以外の場合 → 'ERR'。
ヒントを表示
受信機の値をオンにします。忘れずにデフォルトを指定してください。
3 回の試行後に解決策が利用可能になります
fmt.Stringer を満たすためにメソッドに必要なシグネチャはどれですか?
func (x T) ??? {}要約
fmt.Stringer = interface { String() string }。- これを実装すると、
fmt.Print*が型を表す方法が変わります。 - 列挙型 (
iota)、ドメイン タイプ、コード/識別子の慣用句。 String()内のtでfmt.Sprintf("%s", t)を呼び出さないでください (再帰)。- 規則:
String()の値レシーバー (変更なし、「メソッドセットの予期せぬ事態」を回避)。