Go中級 #7 標準ライブラリツアー
Go の大きな強みの一つは 分厚い標準ライブラリ です。昔の JavaScript が小さい標準をライブラリで補うモデルなら — Go は最初から豊富です。今回の記事はよく使われるものを一気に見渡します。
この記事は深さよりも — 「この用途にこのパッケージがある」というインデックスに近いです。詳しい使い方は各パッケージの 公式ドキュメント が一番良いです。
fmt — フォーマット入出力
#
すでに 基礎 #2 で扱いましたが、もう一度。
fmt.Println("hi") // 改行自動
fmt.Print("改行なし")
fmt.Printf("%s = %d\n", "n", 42)
s := fmt.Sprintf("v=%v", x) // 文字列に
fmt.Errorf("失敗: %w", err) // エラーを作る
// よく使う verb
// %v 基本
// %+v フィールド名を含む
// %#v Go 構文で
// %d %s %t %f %T %qstrings — 文字列ツール
#
strings.Contains("hello", "ell") // true
strings.HasPrefix("hello", "he") // true
strings.HasSuffix("hello", "lo") // true
strings.Index("hello", "ll") // 2
strings.Replace("hello", "l", "L", -1) // heLLo (-1 はすべて)
strings.ReplaceAll("hello", "l", "L") // heLLo
strings.ToUpper("hello") // HELLO
strings.ToLower("HELLO") // hello
strings.TrimSpace(" hello ") // "hello"
strings.Trim("---hi---", "-") // hi
strings.Split("a,b,c", ",") // ["a", "b", "c"]
strings.Join([]string{"a", "b"}, ",") // a,b
strings.Repeat("ab", 3) // ababab
strings.Fields(" a b c ") // ["a", "b", "c"]strings.Builder — 効率的な文字列合成
#
var b strings.Builder
b.WriteString("Hello, ")
b.WriteString("World")
result := b.String() // "Hello, World"ループの中で s += other で文字列をつなげると — 毎回新しいメモリ割り当てが起きます。Builder は内部バッファを再利用するのでずっと効率的です。
strconv — 文字列 ↔ 数値
#
strconv.Itoa(42) // "42"
strconv.Atoi("42") // (42, nil)
strconv.ParseInt("42", 10, 64) // (42, nil) — 基数, ビット幅
strconv.ParseFloat("3.14", 64)
strconv.FormatFloat(3.14, 'f', 2, 64) // "3.14"
strconv.Quote("hi\n") // "\"hi\\n\""ほとんどの場面では Itoa / Atoi / ParseFloat だけ覚えておけば十分です。
bytes — []byte ツール
#
strings の byte スライス版。API がほぼ平行に作られています。
bytes.Contains([]byte("hello"), []byte("ll"))
bytes.Equal(a, b)
bytes.Replace(...)
// Buffer — 可変 byte バッファ
var buf bytes.Buffer
buf.WriteString("hi")
buf.Write([]byte("!"))
fmt.Println(buf.String())bytes.Buffer は io.Reader/io.Writer を両方満たすので — IO でメモリに読んだり書いたりするときによく登場します。
io — IO インターフェース
#
#1 インターフェース で見た核心インターフェース。
type Reader interface { Read(p []byte) (int, error) }
type Writer interface { Write(p []byte) (int, error) }
type Closer interface { Close() error }
io.ReadAll(r) // 全部読んで []byte
io.Copy(dst, src) // src → dst にコピー
io.EOF // 読み込み終了の sentineldata, err := io.ReadAll(resp.Body)
defer resp.Body.Close()os — OS リソース
#
os.Args // コマンドライン引数
os.Getenv("HOME")
os.Setenv("KEY", "value")
os.Exit(1) // プログラム終了
os.Stdin / os.Stdout / os.Stderr // io.Reader/Writer
// ファイル
file, err := os.Open("file.txt") // 読み込み
file, err := os.Create("file.txt") // 書き込み (上書き)
defer file.Close()
data, err := os.ReadFile("file.txt") // 一度に全部読む
err := os.WriteFile("file.txt", data, 0644)
// ディレクトリ
entries, err := os.ReadDir("./")
os.MkdirAll("a/b/c", 0755)
os.Remove("file.txt")
os.RemoveAll("dir")path/filepath — パスを扱う
#
filepath.Join("a", "b", "c") // a/b/c (OSに合わせて)
filepath.Base("/a/b/c.go") // c.go
filepath.Dir("/a/b/c.go") // /a/b
filepath.Ext("c.go") // .go
filepath.Abs("./file") // 絶対パスOS 別の区切り文字(Linux の /、Windows の \)の違いを自動処理。
time — 時間
#
now := time.Now()
yesterday := now.Add(-24 * time.Hour)
nextHour := now.Add(time.Hour)
// 差分
elapsed := time.Since(start) // 経過時間
duration := time.Until(deadline) // 残り時間
// 比較
now.After(other)
now.Before(other)
now.Equal(other)Duration #
time.Second
time.Minute
time.Hour
time.Millisecond
time.Microsecond
time.Nanosecond
3 * time.Second // 3秒
500 * time.Millisecond // 0.5秒フォーマット — Go の独特な方式 #
now := time.Now()
fmt.Println(now.Format("2006-01-02 15:04:05"))
// Go が定めた参照時間
// 2006-01-02 15:04:05.999999999 -0700 MST = Mon Jan 2 15:04:05 MST 2006
// つまり 1 2 3 4 5 6 7他の言語(YYYY-MM-DD)と違って — 特定の参照時刻(2006-01-02 15:04:05)を書いてフォーマットを表現します。最初は不慣れですが、慣れると直感的です。
よく使う定数:
time.RFC3339 // "2006-01-02T15:04:05Z07:00"
time.RFC1123
time.DateOnly // "2006-01-02"
time.TimeOnly // "15:04:05"Parse #
t, err := time.Parse(time.RFC3339, "2026-05-04T10:00:00Z")encoding/json — JSON
#
type User struct {
ID string `json:"id"`
Name string `json:"name"`
Age int `json:"age,omitempty"`
}
// シリアライズ
data, err := json.Marshal(user)
data, err := json.MarshalIndent(user, "", " ") // 見やすく
// デシリアライズ
var u User
err := json.Unmarshal(data, &u)
// ストリーム
encoder := json.NewEncoder(os.Stdout)
encoder.Encode(user)
decoder := json.NewDecoder(file)
err := decoder.Decode(&u)json: タグが #6 構造体 で見た部分です。omitempty は zero value なら結果から除けという意味。
動的 JSON — map[string]any
#
スキーマを知らない JSON を扱うとき。
var data map[string]any
json.Unmarshal(rawJSON, &data)
if name, ok := data["name"].(string); ok {
fmt.Println(name)
}毎回型アサーションが必要で少し面倒です。可能なら struct 定義のほうがすっきりします。
sort — ソート
#
sort.Ints(nums)
sort.Strings(names)
sort.Float64s(values)
// スライスのソート — 関数で
sort.Slice(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})
// 検索 (すでにソート済みのスライスで)
i := sort.SearchInts(nums, target)Generics が入ってきた後 — slices
#
Go 1.21+ に slices パッケージが追加されました。よりモダンな API。
import "slices"
slices.Sort(nums)
slices.SortFunc(users, func(a, b User) int {
return a.Age - b.Age
})
slices.Contains([]string{"a", "b"}, "a")
slices.Index([]int{10, 20, 30}, 20) // 1
slices.Reverse(nums)
slices.Min(nums)
slices.Max(nums)新しいコードでは slices パッケージがますますよく使われています。
maps — マップツール
#
import "maps"
maps.Keys(m) // すべてのキー (イテラブル、スライスに集めるには slices.Collect)
maps.Values(m)
maps.Equal(a, b)
maps.Clone(m)
maps.Delete(m, fn)errors — エラーツール
#
#2 エラー処理 で詳しく扱いました。
errors.New("message")
errors.Is(err, target)
errors.As(err, &target)
errors.Join(err1, err2, err3)
errors.Unwrap(err)net/http — HTTP クライアントとサーバ
#
resp, err := http.Get("https://example.com")
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
// 自前のクライアント
client := &http.Client{Timeout: 5 * time.Second}
req, _ := http.NewRequestWithContext(ctx, "POST", url, body)
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "users")
})
http.ListenAndServe(":8080", nil)実践シリーズ で本格的に扱います。
regexp — 正規表現
#
re := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
match := re.FindStringSubmatch("2026-05-04")
// match: ["2026-05-04", "2026", "05", "04"]
re.MatchString("foo")
re.ReplaceAllString("a1 b2", "X")
re.FindAllString("a1 b2 c3", -1)bufio — バッファ付き IO
#
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// ...
}
if err := scanner.Err(); err != nil {
// ...
}
// または Reader
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')大容量ファイルを一行ずつ読むとき — os.ReadFile よりメモリに安全なパターンです。
log と log/slog — ロギング
#
昔の log は単純な出力。
log.Println("info")
log.Fatalf("fatal: %v", err) // 出力後 os.Exit(1)Go 1.21+ の log/slog — 構造化ロギング(key-value ペア)。
import "log/slog"
slog.Info("user logged in", "user_id", "u1", "ip", "127.0.0.1")
slog.Error("DB 失敗", "err", err)
// JSON 出力
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
slog.SetDefault(logger)JSON 出力は — ログ分析ツール(Datadog、Grafana など)との統合がとても楽です。新しいコードでは slog がますます標準になっています。
flag — コマンドラインフラグ
#
import "flag"
var (
host = flag.String("host", "localhost", "サーバアドレス")
port = flag.Int("port", 8080, "ポート")
verbose = flag.Bool("v", false, "verbose")
)
func main() {
flag.Parse()
fmt.Println(*host, *port, *verbose)
}./app --host=0.0.0.0 --port=3000 -vCLI により豊富な機能が必要なら — cobra、kong のような外部ライブラリ。標準 flag だけでも小さなツールには十分です。
その他のよく使うパッケージ — 短く #
crypto/rand セキュア乱数
crypto/sha256 ハッシュ
encoding/base64
encoding/hex
encoding/csv
encoding/xml
hash/fnv 高速ハッシュ (セキュア X)
math
math/rand 非セキュア乱数
net 低レベルネットワーキング
net/url URL パース
sync Mutex, WaitGroup, Once, Map
sync/atomic 原子的演算
unicode Unicode ツール
unicode/utf8 UTF-8 エンコーディングまとめ #
今回の記事は インデックス に近い記事でした。詳しい使い方は pkg.go.dev/std で各パッケージを見てください。
よく出会う場面:
- 文字列 →
strings、fmt、strconv - 時間 →
time - JSON →
encoding/json - ソート →
sortまたはslices(Go 1.21+) - HTTP →
net/http - ロギング →
log/slog(Go 1.21+) - IO →
os、io、bufio
中級シリーズを終えて #
7編で扱った内容:
- インターフェース — 暗黙的実装 (#1)
- エラー処理 — wrap、Is/As、panic (#2)
- ゴルーチンとチャネル — 並行性入門 (#3)
- select とタイムアウト — 複数チャネルを扱う (#4)
- context — 標準キャンセル/タイムアウトツール (#5)
- テスティング — testing パッケージと table-driven (#6)
- 標準ライブラリツアー — よく出会うパッケージ(今回の記事)
ここまで掴めば Go で堅牢なコードを書けます。次の 上級シリーズ では — 並行性パターンの深掘り、メモリモデル、ジェネリクス、reflect のような一段上のツールを扱います。