Go言語入門:効果的なGo -データ:Printing(1)-

スポンサーリンク
Go言語入門:効果的なGo -データ:Printing(1)- ノウハウ
Go言語入門:効果的なGo -データ:Printing(1)-
この記事は約5分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

本日は、Go言語を効果的に使うためのガイドラインについて解説しています。

スポンサーリンク

背景

Go言語を学び始めて、より良いコードを書きたいと思い、Go言語の公式ドキュメント「Effective Go」を知りました。これは、いわば「Goらしいコードの書き方指南書」になります。単に動くコードではなく、効率的で保守性の高いコードを書くためのベストプラクティスが詰まっているので、これを読んだ時の内容を備忘として残しました。

Printing(出力)

Go言語でのフォーマット出力は、C言語のprintfファミリーと似たスタイルを使用していますが、より豊富で汎用的です。これらの関数はfmtパッケージに含まれており、大文字で始まる名前を持っています:fmt.Printffmt.Fprintffmt.Sprintfなど。文字列関数(Sprintfなど)は、提供されたバッファを埋めるのではなく、文字列を返します。

フォーマット文字列を提供する必要はありません。PrintfFprintfSprintfのそれぞれに対して、別のペアの関数があります。例えばPrintPrintlnです。これらの関数はフォーマット文字列を取らず、代わりに各引数に対してデフォルトのフォーマットを生成します。Printlnバージョンは引数間に空白を挿入し、出力に改行を追加しますが、Printバージョンは両側のオペランドが文字列でない場合にのみ空白を追加します。この例では、各行が同じ出力を生成します。

fmt.Printf("Hello %d\n", 23)
fmt.Fprint(os.Stdout, "Hello ", 23, "\n")
fmt.Println("Hello", 23)
fmt.Println(fmt.Sprint("Hello ", 23))

フォーマット印刷関数fmt.Fprintとその仲間たちは、第一引数としてio.Writerインターフェースを実装する任意のオブジェクトを取ります;変数os.Stdoutos.Stderrは馴染みのあるインスタンスです。

ここで C言語から分岐し始めます。まず、%dなどの数値フォーマットは、符号や大きさのフラグを取りません;代わりに、印刷ルーチンは引数の型を使用してこれらの属性を決定します。

var x uint64 = 1<<64 - 1
fmt.Printf("%d %x; %d %x\n", x, x, int64(x), int64(x))

出力:

18446744073709551615 ffffffffffffffff; -1 -1

解説

1. Go言語の出力関数の種類

Go言語には大きく分けて3つの出力方法があります:

Printf系(フォーマット指定)

  • fmt.Printf:標準出力にフォーマット指定で出力
  • fmt.Fprintf:指定した出力先にフォーマット指定で出力
  • fmt.Sprintf:文字列として返す(画面には出力しない)

Print系(基本出力)

  • fmt.Print:そのまま出力
  • fmt.Fprint:指定した出力先に出力
  • fmt.Sprint:文字列として返す

Println系(改行付き出力)

  • fmt.Println:自動でスペース挿入+改行
  • fmt.Fprintln:指定した出力先に改行付きで出力
  • fmt.Sprintln:文字列として返す(改行付き)

2. 実際の使い方

// これらは全て "Hello 23" を出力します
fmt.Printf("Hello %d\n", 23)           // %d で数値をフォーマット
fmt.Fprint(os.Stdout, "Hello ", 23, "\n")  // 標準出力に直接書き込み
fmt.Println("Hello", 23)               // 自動でスペースと改行を追加
fmt.Println(fmt.Sprint("Hello ", 23))  // 一度文字列にしてから出力

3. C言語との大きな違い

C言語の場合:

printf("%ld", number);  // データ型を明示的に指定する必要がある

Go言語の場合:

fmt.Printf("%d", number)  // Go が自動的に型を判断してくれる

4. 型の自動判断の例

var x uint64 = 1<<64 - 1  // 18446744073709551615(64ビット最大値)
fmt.Printf("%d %x; %d %x\n", x, x, int64(x), int64(x))

何が起こているか:

  • xuint64型(符号なし64ビット整数)
  • 1<<64 - 1は64ビットの最大値(全てのビットが1)
  • int64(x)で符号付き64ビット整数に変換
  • 符号なし最大値が符号付きでは-1になる(コンピューターの内部表現の仕組み)

出力結果の意味:

  • 18446744073709551615:uint64の10進数表示
  • ffffffffffffffff:uint64の16進数表示(fが16個=64ビット全て1)
  • -1:int64の10進数表示
  • -1:int64の16進数表示

5. io.Writer インターフェース

fmt.Fprint系の関数は、出力先を自由に指定できます:

  • os.Stdout:画面(標準出力)
  • os.Stderr:エラー出力
  • ファイル
  • ネットワーク接続
  • その他、io.Writerを実装する任意のオブジェクト

これにより、同じ関数で様々な場所に出力できる柔軟性があります。

おわりに 

本日は、Go言語を効果的に使うためのガイドラインについて解説しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました