Rust

Rust 実践講座 #7 リリース最適化とクロスコンパイル — 小さく速いバイナリをどこでも
読了 5分

Rust 実践講座 #7 リリース最適化とクロスコンパイル — 小さく速いバイナリをどこでも

配布準備の前半です。[profile.release] で締める最適化(lto、codegen-units、strip)とそれぞれの代償、panic = "abort" を安易に有効にしてはいけない理由、バイナリサイズが縮む過程、そして rustup target で行うクロスコンパイル — 特に glibc 依存をなくして古いサーバーでも動く musl 静的リンクビルドと、リンカ問題を Docker で迂回する cross ツールまで扱います。

Rust 実践講座 #6 テスト — パーサーの単体テストから CLI の統合テストまで
読了 4分

Rust 実践講座 #6 テスト — パーサーの単体テストから CLI の統合テストまで

loglens に安全網を張ります。同じファイルに置く #[cfg(test)] の単体テスト(パーサーの正常・境界・失敗ケース)、tests/ ディレクトリの統合テスト、assert_cmd と predicates でビルド済みバイナリを実際に実行して出力と終了コードを検証する CLI テスト、tempfile で作る一時ログファイル、そして cargo test がテストを並列実行するという事実が持つ意味まで扱います。

Rust 実践講座 #5 rayon 並列化 — データ競合のない map-reduce
読了 5分

Rust 実践講座 #5 rayon 並列化 — データ競合のない map-reduce

集計を複数コアに分けます。並列化が得になる条件(CPU バウンド)とストリーミングから丸ごと読みへ戦略を変える理由、rayon の par_lines と fold・reduce で作るスレッドごとの部分集計と統合、Mutex で 1 つの HashMap を共有すると遅くなる理由(ロック競合)、そして共有可変状態のミスをコンパイラが捕まえる場面まで扱います。

Rust 実践講座 #4 イテレータ実践 — 集計と top-N、そしてリリースビルドの差
読了 4分

Rust 実践講座 #4 イテレータ実践 — 集計と top-N、そしてリリースビルドの差

パーサーの上に分析を載せます。パース失敗を数えながら成功だけを流す集計構造、HashMap の entry で作るステータスコード分布、ソートで取り出す top-N、コマンド 2 つ(stats・top)の完成、そして Instant で実測する debug と release ビルドの性能差(なぜ数十倍になるのか、なぜ release が既定値ではないのか)まで扱います。

Rust 実践講座 #3 ファイル IO とパース — BufReader で読み、ログ 1 行を構造体へ
読了 4分

Rust 実践講座 #3 ファイル IO とパース — BufReader で読み、ログ 1 行を構造体へ

大きなファイルを扱う 2 つの基本を固めます。全体をメモリに載せる read_to_string と行単位で流す BufReader の選択基準、システムコールとバッファリングの関係、アクセスログ 1 行を LogEntry 構造体に変えるパーサー(引用符の処理、ステータスコードの変換、第 2 回 ParseError の実戦投入)、そして serde で JSON Lines ログまで受け付ける拡張を扱います。

Rust 実践講座 #2 エラー設計 — anyhow と thiserror、死に方を設計する
読了 5分

Rust 実践講座 #2 エラー設計 — anyhow と thiserror、死に方を設計する

CLI ツールにおいてエラーメッセージはユーザーインターフェースの一部です。アプリケーション層の既定値である anyhow(main が anyhow::Result を返し、context で文脈を積む)と、呼び出し側が種類で分岐できる具体的なエラー型を作るライブラリ層の thiserror の役割分担、2 つのクレートを選ぶ判断基準、そして終了コードまで、loglens のエラー経路を設計します。

Rust 実践講座 #1 プロジェクト設計と clap — サブコマンド CLI の骨組みを立てる
読了 5分

Rust 実践講座 #1 プロジェクト設計と clap — サブコマンド CLI の骨組みを立てる

基礎講座で学んだ文法で実際のツールを作る実践 8 回を始めます。作るのはアクセスログ分析 CLI の loglens です。なぜ CLI ツールが Rust の代表的な舞台なのか(単一バイナリ、起動速度)、clap の derive 方式でサブコマンド(stats・top・errors)を列挙型 1 つで宣言する方法、自動生成される --help、そして全 8 回の設計地図まで扱います。

Rust 基礎講座 #9 ライフタイムとモジュール — 注釈が必要になる瞬間、クレートで仕上げる
読了 5分

Rust 基礎講座 #9 ライフタイムとモジュール — 注釈が必要になる瞬間、クレートで仕上げる

基礎講座の最終回です。第 4 回のダングリング参照の遮断がどう働いていたのかをライフタイム(lifetime)で説明します。missing lifetime specifier エラーが出る瞬間、ライフタイム注釈の本当の意味(寿命を延ばすのではなく関係を宣言する)、ほとんどの場合に表記が省略される理由。続いて mod と pub でコードを分けるモジュールシステム、crates.io の外部クレートの使い方、そして講座後の学習経路まで整理します。

Rust 基礎講座 #8 トレイトとジェネリクス — 継承がない言語で共通の動作を定義する
読了 5分

Rust 基礎講座 #8 トレイトとジェネリクス — 継承がない言語で共通の動作を定義する

これまで先送りしてきた概念を回収する回です。共通の動作を定義するトレイト(trait)と既定実装、型を一般化するジェネリクスとトレイト境界、derive が自動生成する標準トレイト(Debug・Clone・Copy・PartialEq)、ジェネリクスがランタイムコストなしにコンパイルされる単相化、そして Box<dyn Error> の dyn が意味する動的ディスパッチまで扱います。

Rust 基礎講座 #7 コレクションとイテレータ — Vec・String・HashMap、for の代わりにチェーン
読了 4分

Rust 基礎講座 #7 コレクションとイテレータ — Vec・String・HashMap、for の代わりにチェーン

実務コードの本体である 3 つのコレクションを扱います。可変長リストの Vec とインデックスの代わりに get を使う理由、なぜ String はインデックスでアクセスできないのか(UTF-8 とバイト・文字の違い)、HashMap と entry API、そして for 文を map・filter・collect のチェーンに置き換えるイテレータスタイルと遅延評価まで扱います。

Rust 基礎講座 #6 エラー処理 — Result と ? 演算子、panic と unwrap の境界
読了 5分

Rust 基礎講座 #6 エラー処理 — Result と ? 演算子、panic と unwrap の境界

例外(exception)のない Rust のエラー処理を扱います。失敗の可能性を戻り値の型に現す Result、match の入れ子を 1 文字に縮めてエラーを伝播する ? 演算子、main が Result を返す実用形、そして unwrap・expect・panic をいつ使ってよく、いつ使ってはいけないのかの判断基準まで扱います。

Rust 基礎講座 #5 構造体と列挙型 — match と Option、null がない言語の設計
読了 4分

Rust 基礎講座 #5 構造体と列挙型 — match と Option、null がない言語の設計

データを構造化する 2 本の軸、構造体(struct)と列挙型(enum)を扱います。impl ブロックでメソッドを付ける方法、バリアントごとに異なるデータを持てる Rust 列挙型の表現力、すべてのケースを検査したかをコンパイラが強制する match、そして null の代わりに「値がないかもしれない」を型で表す Option まで、Rust コードの骨格になる道具を扱います。