🍚

Goのfmt.Printfの幅と精度は引数で指定できる

2022/08/26に公開

幅と精度とは

Goの標準ライブラリであるfmtパッケージでは、fmt.Printf関数やfmt.Sprintf関数など、書式を指定して表示や文字列を生成する関数が提供されています。Go1.19では、バイト列([]byte型)を生成するfmt.Appendf関数も追加されました。

書式の中では、%dや%sのようにverbを指定して、表示方法(文字列の組み立て方)を指定します。%2dや%2.3fのように、幅や精度を指定ができることはCのprintf関数と似た機能なのでよく知ってる方も多いでしょう[1]

幅と精度を引数で指定する

幅と精度は、実は引数で指定できます。頑張ってfmt.Sprintf("%%%dd", width)のように書式文字列を生成する必要はありません。幅や精度に*と記述すると引数で値を指定できます。

たとえば、幅の場合は次のように書けます。

fmt.Println("123456789")
fmt.Printf("%*d", 4, 10)

The Go Playgroundで動かす

この場合は幅が4となり、2つスペースをあけて10が表示されます。

精度は次のように指定できます。精度が3となり、1.556が表示されます。

fmt.Printf("%.*f", 3, 1.5555)

The Go Playgroundで動かす

もちろん、次のように幅と精度に同時に*を指定できます。幅が7で精度が3なので、2つスペースをあけて1.556と表示されます。

fmt.Printf("%*.*f", 7, 3, 1.5555)

The Go Playgroundで動かす

幅や精度に*を指定した場合、verbと同じようにインデクサで対応する引数を指定できます。たとえば、次のように指定すると引数を逆順に対応づけできます。

fmt.Printf("%[3]*.[2]*[1]f",1.5555, 3, 7)

The Go Playgroundで動かす

fmtパッケージは公式ドキュメントを読まずとも使える部分は多いですが、読んでみると案外知られていない機能も多いでしょう。ぜひ定期的にドキュメントに目を通してみると良いでしょう。

脚注
  1. 実際には幅はCではバイト数でGoではUnicodeのコードポイント数(runeの数)になっています。 ↩︎

Discussion