Lixv

Lixv

Go fmtパッケージの詳細解説

fmt パッケージ入門ガイド

多くの人が Go 言語に入門する際、公式サイトのfmt.Println("Hello World")から始めることが多いです。この記事では、fmtパッケージが他にどのようなことができるのかを詳しく見ていきましょう。

Go 言語では、fmt パッケージを使用してフォーマットされた入出力操作を行うことがよくあります。ほとんどの場合、Print...、Sprint...、Errorf などの少数の関数しか使用せず、一般的なプレースホルダーのみを使いますが、これは fmt パッケージの他の特性を理解する必要がないことを意味しません。

fmt パッケージの概要#

fmt パッケージは、C 言語に似たフォーマットされた入出力関数を実装しています。

Print 系列関数#

func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)

Print 系列関数は、内容を標準出力に出力します。Print 関数は内容を直接出力し、Printf はフォーマットされた出力をサポートし、Println は毎回出力する内容の後に改行文字を追加します。

例えば:

fmt.Print("123")
fmt.Printf("%d", 456)
fmt.Print("789")
fmt.Printf("%d\n", 123)
fmt.Println("123")
fmt.Println("456")

出力:

123456789123
123
456

Sprint 系列関数#

func Sprint(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string
func Sprintln(a ...interface{}) string

Sprint 系列関数は、内容を文字列として出力します。違いは、Sprint が内容を直接出力し、Sprintf が後ろの内容を対応するプレースホルダーにマッピングし、Sprintln が内容の後に改行文字を追加することです。

例えば:

s1 := fmt.Sprint("123")
s2 := fmt.Sprintf("name:%s,age:%d", "Lixin", 21)
s3 := fmt.Sprintln("456")
fmt.Println(s1, s2, s3)

出力:

123 name:Lixin,age:21 456

Fprint 系列関数#

func Fprint(w io.Writer, a ...interface{}) (n int, err error)
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)

Fprint 系列関数は、内容を io.Writer インターフェースを実装した変数に出力します。一般的な使い方は、ファイルに内容を書き込むことですが、端末に出力することもできます(あまり一般的ではありません)。

例えば、標準出力に内容を書き込む:

fmt.Fprintln(os.Stdout, "標準出力に内容を書き込む")
fileObj, err := os.OpenFile("./output.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
    panic(err)
}
name := "Lixin"
// 開いたファイルハンドルに内容を書き込む
fmt.Fprintf(fileObj, "ファイルに情報を書き込む\nname: %s\nage: %d", name, 21)

出力される内容は:

標準出力に内容を書き込む

ファイル output.txt の内容は:

ファイルに情報を書き込む
name: Lixin
age: 21

Errors#

Errorf は Printf に似ていますが、その文字列を含むエラーを返します。

通常、私たちはこのようなエラーを返します:

var err error
// ...
return fmt.Errorf("Error: %v", err)

Scan 系列関数#

func Scan(a ...interface{}) (n int, err error)
func Scanf(format string, a ...interface{}) (n int, err error)
func Scanln(a ...interface{}) (n int, err error)

Scan 系列関数は、標準入力からテキストをスキャンし、format パラメータで指定された形式に基づいて対応する値を a... のパラメータにマッピングします。

Scan 関数は空白で入力値を区別し、Scanf は format で値を区別し、Scanln は改行でスキャンを停止します。

例えば:

var name string
var age int
fmt.Scanln(&name, &age)
fmt.Printf("name: %s, age: %d", name, age)

入力 Lixin 21、出力:

name: Lixin, age: 21

Scanf の例:

var name string
var age int
fmt.Scanf("name:%s age:%d", &name, &age)
fmt.Printf("name: %s, age: %d", name, age)

入力 name:Lixin age:21、出力:

name: Lixin, age: 21

Fscan 系列関数#

func Fscan(r io.Reader, a ...interface{}) (n int, err error)
func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)

Fscan 系列関数は、標準入力からデータを読み取ることができます。例えば、ファイルやコマンドラインからの入力です。

ファイルから内容を読み取る場合:

var s string
f, _ := os.OpenFile("./output.txt", os.O_CREATE|os.O_RDWR, 0644)

reader := bufio.NewReader(f)
fmt.Fscan(reader, &s)
fmt.Printf("読み取った文字列は:%s", s)

もしファイル output.txt の内容が file.Outputn ame: Lixinage: 21 であれば、出力は 読み取った文字列は:file.Outputn になります。なぜなら、Fscan はデフォルトで空白を区切り文字として使用し、空白の後の内容を認識できないからです。

標準入力から内容を読み取る場合は、以下のコードを使用できます:

var s string
reader := bufio.NewReader(os.Stdin)
fmt.Fscan(reader, &s)
fmt.Printf("あなたの入力内容は:%s", s)

入力 Hello, Lixin、出力 あなたの入力内容は:Hello、同様にこの関数は空白を認識できません。

Fscanln 関数は改行文字でスキャンを停止し、Fscanf は Scanf に似ており、対応する改行文字をマッピングするために使用されます。この 2 つの関数の使い方は似ています。

また、ここで bufio パッケージの ReadString 関数についても触れておきます。この関数は指定された io.Reader から 1 行の文字列を読み取り、指定された区切り文字に達するまで読み取ります。関数のシグネチャは以下の通りです:

func (b *Reader) ReadString(delim byte) (string, error)

例えば、ファイル output.txt の最初の行を読み取り、空白を区切り文字として使用する場合は、次のように書けます:

f, _ := os.OpenFile("./output.txt", os.O_RDWR, 0644)
reader := bufio.NewReader(f)
line, err := reader.ReadString(' ')
if err != nil {
    fmt.Println(err)
    return
}
fmt.Printf("読み取った文字列は:%s", line)

もしファイル output.txt の内容が file.Outputn ame: Lixinage: 21 であれば、出力は 読み取った文字列は:file.Outputn になります。なぜなら、ReadString は空白に出会った時点で読み取りを停止するからです。

Sscan 系列関数#

func Sscan(str string, a ...interface{}) (n int, err error)
func Sscanln(str string, a ...interface{}) (n int, err error)
func Sscanf(str string, format string, a ...interface{}) (n int, err error)

Sscan は、文字列からデータを読み取り、指定された変数にフォーマットするための関数です。

例えば:

str := "1 2 3"
var a, b, c int
n, err := fmt.Sscan(str, &a, &b, &c)
if err != nil {
    fmt.Println(err)
    return
}
fmt.Printf("読み取った数は %d 個で、それぞれ:%d,%d,%d", n, a, b, c)

この関数を実行すると、出力は:

読み取った数は 3 個で、それぞれ:1,2,3

Go 言語のfmtパッケージには、フォーマットされた出力に使用できる一般的なプレースホルダーがいくつかあります。以下は、いくつかの一般的なプレースホルダーとその使用方法です:

  • %v:汎用のプレースホルダーで、任意の型の値をフォーマットできます。値の型に応じて適切な形式が自動的に選択されます。
  • %d:整数型(符号付き整数および符号なし整数)をフォーマットするために使用されます。
  • %f:浮動小数点数型をフォーマットするために使用されます。
  • %s:文字列型をフォーマットするために使用されます。
  • %t:ブール型をフォーマットするために使用されます。
  • %c:文字型をフォーマットするために使用されます。
  • %p:ポインタ型をフォーマットするために使用されます。

以下は、これらのプレースホルダーを使用する方法を示すいくつかの例です:

name := "Lixin"
age := 21
pi := 3.14159
isStudent := true

fmt.Printf("Name: %s, Age: %d\n", name, age)  // 出力:Name: Lixin, Age: 21
fmt.Printf("Pi: %.2f\n", pi)                  // 出力:Pi: 3.14
fmt.Printf("Is student: %t\n", isStudent)     // 出力:Is student: true

フォーマットされた文字列では、プレースホルダーはパーセント記号 % の後に文字が続く形で表されます。%d%f などのプレースホルダーの後に追加のパラメータを加えてフォーマットの方法を制御することができます。例えば、%f プレースホルダーは .2 を使用して浮動小数点数を小数点以下 2 桁に制限できます。

Printf関数の他にも、SprintfFprintfなどの関数でもこれらのプレースホルダーを使用できます。Sprintf関数はフォーマットされた結果を文字列として返し、Fprintf関数はフォーマットされた結果を指定されたio.Writerに書き込みます。

result := fmt.Sprintf("Name: %s, Age: %d", name, age)
fmt.Println(result)  // 出力:Name: Lixin, Age: 21

file, _ := os.Create("output.txt")
fmt.Fprintf(file, "Name: %s, Age: %d", name, age)
file.Close()

まとめ#

これらはfmtパッケージで一般的なプレースホルダーとその使用方法です。具体的な詳細については公式サイトを参照してください。そこには非常に詳しく書かれています。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。