Go中級 #7 標準ライブラリツアー

読了 6分

Go の大きな強みの一つは 分厚い標準ライブラリ です。昔の JavaScript が小さい標準をライブラリで補うモデルなら — Go は最初から豊富です。今回の記事はよく使われるものを一気に見渡します。

この記事は深さよりも — 「この用途にこのパッケージがある」というインデックスに近いです。詳しい使い方は各パッケージの 公式ドキュメント が一番良いです。

fmt — フォーマット入出力 #

すでに 基礎 #2 で扱いましたが、もう一度。

fmt
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 %q

strings — 文字列ツール #

strings
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 — 効率的な文字列合成 #

Builder
var b strings.Builder
b.WriteString("Hello, ")
b.WriteString("World")
result := b.String()    // "Hello, World"

ループの中で s += other で文字列をつなげると — 毎回新しいメモリ割り当てが起きます。Builder は内部バッファを再利用するのでずっと効率的です。

strconv — 文字列 ↔ 数値 #

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
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.Bufferio.Reader/io.Writer を両方満たすので — IO でメモリに読んだり書いたりするときによく登場します。

io — IO インターフェース #

#1 インターフェース で見た核心インターフェース。

io の核心
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               // 読み込み終了の sentinel
よく使うパターン
data, err := io.ReadAll(resp.Body)
defer resp.Body.Close()

os — 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
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 — 時間 #

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 #

Duration
time.Second
time.Minute
time.Hour
time.Millisecond
time.Microsecond
time.Nanosecond

3 * time.Second                    // 3秒
500 * time.Millisecond             // 0.5秒

フォーマット — Go の独特な方式 #

time フォーマット
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 定数
time.RFC3339         // "2006-01-02T15:04:05Z07:00"
time.RFC1123
time.DateOnly        // "2006-01-02"
time.TimeOnly        // "15:04:05"

Parse #

Parse
t, err := time.Parse(time.RFC3339, "2026-05-04T10:00:00Z")

encoding/json — 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 を扱うとき。

動的 JSON
var data map[string]any
json.Unmarshal(rawJSON, &data)

if name, ok := data["name"].(string); ok {
	fmt.Println(name)
}

毎回型アサーションが必要で少し面倒です。可能なら struct 定義のほうがすっきりします。

sort — ソート #

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。

slices (Go 1.21+)
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 — マップツール #

maps (Go 1.21+)
import "maps"

maps.Keys(m)        // すべてのキー (イテラブル、スライスに集めるには slices.Collect)
maps.Values(m)
maps.Equal(a, b)
maps.Clone(m)
maps.Delete(m, fn)

errors — エラーツール #

#2 エラー処理 で詳しく扱いました。

errors
errors.New("message")
errors.Is(err, target)
errors.As(err, &target)
errors.Join(err1, err2, err3)
errors.Unwrap(err)

net/http — 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 サーバ
http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "users")
})
http.ListenAndServe(":8080", nil)

実践シリーズ で本格的に扱います。

regexp — 正規表現 #

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 #

bufio
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 よりメモリに安全なパターンです。

loglog/slog — ロギング #

昔の log は単純な出力。

log 旧パッケージ
log.Println("info")
log.Fatalf("fatal: %v", err)   // 出力後 os.Exit(1)

Go 1.21+ の log/slog構造化ロギング(key-value ペア)。

slog (Go 1.21+)
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 — コマンドラインフラグ #

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 -v

CLI により豊富な機能が必要なら — cobrakong のような外部ライブラリ。標準 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 で各パッケージを見てください。

よく出会う場面:

  • 文字列 → stringsfmtstrconv
  • 時間 → time
  • JSON → encoding/json
  • ソート → sort または slices(Go 1.21+)
  • HTTP → net/http
  • ロギング → log/slog(Go 1.21+)
  • IO → osiobufio

中級シリーズを終えて #

7編で扱った内容:

  1. インターフェース — 暗黙的実装 (#1)
  2. エラー処理 — wrap、Is/As、panic (#2)
  3. ゴルーチンとチャネル — 並行性入門 (#3)
  4. select とタイムアウト — 複数チャネルを扱う (#4)
  5. context — 標準キャンセル/タイムアウトツール (#5)
  6. テスティング — testing パッケージと table-driven (#6)
  7. 標準ライブラリツアー — よく出会うパッケージ(今回の記事)

ここまで掴めば Go で堅牢なコードを書けます。次の 上級シリーズ では — 並行性パターンの深掘り、メモリモデル、ジェネリクス、reflect のような一段上のツールを扱います。

X