Goの出力で最初に迷ったこと

PrintlnPrintf は役割が違う

前回 は、hello-worldで go fmtgo vetgo build の流れを触りました。

次に分かりやすく引っかかったのが、fmt.Printlnfmt.Printf でした。

Pythonだと、とりあえず print(value) で雑に出せます。Goにも似た感じで fmt.Println があります。一方で、fmt.Printf はもう少し「出し方を指定する」関数でした。

補足すると、Goには fmt を使わない組み込みの print / println もあります(公式)。ただ、自分が今回触ったのは標準ライブラリの fmt パッケージ(公式)です。

Println は雑に値を見る

改行付きで標準的に表示する

Println は、渡した値を標準的な形で表示して、最後に改行してくれます。

fmt.Println("hello", 20)

学習中に値を見たいだけなら、まずこれで十分そうです。

Pythonの print() に近い感覚で使えるので、最初は fmt.Println で値を見るところから始めるのが分かりやすかったです。

組み込みの println とは分けて考える

Goには組み込み関数として print / println もあります。ただ、今回の学習メモでは標準ライブラリの fmt.Println / fmt.Printf を主に見ています。

自分の理解としては、通常の学習やアプリケーションコードでは fmt パッケージを使う前提で考えた方が整理しやすいです。

Printf は形式を指定する

format stringを先に渡す

一方で Printf は、思ったよりちゃんと「形式を指定する」関数でした。

fmt.Printf("age=%d\n", 20)

代表的には、%d は整数、%s は文字列、%f は小数、%v は標準的な表示です。

fmt.Printf("%d\n", 20)
fmt.Printf("%s\n", "hello")
fmt.Printf("%v\n", 20)

よく使うverbだけ先に覚える

fmt.Printf のverbはかなりあります。全部を最初に覚える必要はなさそうなので、まずはよく使いそうなものだけを置いておきます。

verb 使いどころ
%v 値を標準的な形式で表示
%+v 構造体ではフィールド名も表示
%#v Goの構文に近い表現で表示
%T 値の型を表示
%d 10進数の整数
%s 文字列
%f 小数
%t true / false
%% % そのもの

幅や小数点以下の桁数も指定できます。たとえば %9f%.2f%9.2f のような書き方です。詳しくは fmt パッケージ(公式)を見るのが早そうです。

Printf の第1引数で詰まった

第1引数は文字列にする

なので、これはエラーになります。

i := 20
fmt.Printf(i)

Printf の第1引数は、フォーマット文字列である必要があります。iint なので、そこには置けません。

最初は「え、Printfってけっこう厳しいんだな」と思いました。ただ、少し見方を変えると、Printf は出力を細かく制御したいときの道具なんですよね。

go vet でも見つけられる

この手の怪しい使い方は、go vet公式)でも見つかることがあります。

go vet ./

hello-worldの段階で go vet を一緒に触っておくと、こういう「コンパイルは通るかもしれないけど怪しい」箇所を見る習慣が少しつきそうです。

雑に見るならPrintln、形を決めるならPrintf

役割を分けると見えやすい

自分の中では、こう整理しました。

fmt.Println(value)        // とりあえず見る
fmt.Printf("%v\n", value) // 形式を決めて見る

雑に見るなら Println。形を決めるなら Printf

役割が分かれているだけでした。こういう小さいところにも、Goの「曖昧にせず、必要なところは指定する」感じが出ている気がします。

次は Goの :=varconst で型と変更可否を見る に進みます。