メインコンテンツにスキップ
モジュール 6 · レッスン 4 / 5コース内の 29/50~10 min
モジュールのレッスン (4/5)

ストリンガーインターフェイス

fmt.Stringer は、おそらくすべての中で最もよく使用される標準インターフェイスです。 Go の標準ライブラリ。それは力の完璧なデモンストレーションです 小さなインターフェイスの。

意味

Go
type Stringer interface {
    String() string
}

一枚のサイン。 String() string を定義する型はすべて次の条件を満たします。 それ。そして、fmt はこのインターフェイスを認識します。値を渡すと、 fmt.Print*、Stringer を実装する場合は、String() の結果 デフォルトの表現の代わりに使用されます。

例

Go
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 との共通パターン

Go
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 ERR

String() がない場合、fmt.Println(OK) は 0 を出力します。 String() を使用すると、 シンボリック名を出力します。 stringer ツールはこのパターンを自動的に生成します。

無限再帰に注意してください

Go
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() に使用されます (これは「ビュー」ですが、そうではありません) 何かを変更します)。

試してみてください

運動#go.m6.l4.e1
試行回数: 0読み込み中…

Point に String() を実装して、(X,Y) を返すようにします。

エディターを読み込み中…
ヒントを表示

`fmt.Sprintf` を使用してフィールドをフォーマットします。

3 回の試行後に解決策が利用可能になります

運動#go.m6.l4.e2
試行回数: 0読み込み中…

型 Status (int) に String() を実装します: 0 → 'OK'、1 → 'WARN'、それ以外の場合 → 'ERR'。

エディターを読み込み中…
ヒントを表示

受信機の値をオンにします。忘れずにデフォルトを指定してください。

3 回の試行後に解決策が利用可能になります

Quiz#go.m6.l4.e3
準備完了

fmt.Stringer を満たすためにメソッドに必要なシグネチャはどれですか?

Go
func (x T) ??? {}
回答の選択肢

要約

  • fmt.Stringer = interface { String() string }。
  • これを実装すると、fmt.Print* が型を表す方法が変わります。
  • 列挙型 (iota)、ドメイン タイプ、コード/識別子の慣用句。
  • String() 内の t で fmt.Sprintf("%s", t) を呼び出さないでください (再帰)。
  • 規則: String() の値レシーバー (変更なし、「メソッドセットの予期せぬ事態」を回避)。