実践Rust入門 言語仕様から開発手法まで
技術評論社
著者:keen、河野達也、小松礼人
はじめに
目次
第1部 基礎編
第1章 Rustの特徴
1-1 Rustの特徴
1-2 最も愛されている言語
1-3 Rustの起源
コラム 名前の由来
1-4 なぜRustなのか?
1-4-1 トップクラスのパフォーマンス
マシンコードへのコンパイル
静的型付け
ゼロコスト抽象化
GCを行わない軽量なランタイム
1-4-2 安全なシステムプログラミング言語
CとC++の問題
他の言語およびRustにおける解決法
型安全性
メモリ安全性
マルチスレッドプログラミングにおけるデータ競合の回避
アンセーフなコードのサポート
1-4-3 生産性を高めるモダンな機能
1-4-4 シングルバイナリ,クロスコンパイル
1-4-5 他言語との連携が容易
1-5 導入事例
1-5-1 Dropbox – Magic Pocket
1-5-2 ドワンゴ – Frugalos
1-5-3 npmレジストリ
1-5-4 AWS Firecracker
1-5-5 Mozilla Firefox
並列化とGPU活用による高速化
CSSエンジンの脆弱性について
新たな章に突入したFirefox
第2章 はじめてのRustプログラム
2-1 インストール
2-1-1 本書が対象とする環境
2-1-2 ツールチェイン,リンカ,ABI
2-1-3 rustup
2-1-4 Rustツールチェインのインストール
コマンド検索パスの設定
インストール結果の確認
2-1-5 リンカのインストール(Linux)
2-1-6 リンカのインストール(macOS)
2-1-7 リンカのインストール(Windows MSVC)
2-2 Hello Worldプログラム
2-2-1 パッケージの作成
2-2-2 binクレートとlibクレート
2-2-3 Cargo.tomlファイル
2-2-4 src/main.rsファイル
2-2-5 パッケージのビルド
2-2-6 プログラムの実行
2-2-7 プログラムの内容
関数の引数と戻り値
println!マクロ
2-3 ソースコードエディタの導入
2-3-1 Rustをサポートする主なエディタとIDE
2-3-2 Visual Studio Code(VS Code)の特徴
2-3-3 VS Codeのインストール
2-3-4 Rust RLS拡張機能のインストール
2-3-5 基本的な使い方
2-4 RPN計算機プログラムとデバッガによる実行
2-4-1 プログラムの作成
main関数
rpn関数
apply2関数
コラム ジェネリクスにおけるトレイト境界について
2-4-2 デバッガのセットアップ(LinuxとmacOS)
2-4-3 CodeLLDB拡張機能のインストール
2-4-4 デバッガのセットアップ(Windows MSVC)
2-4-5 パッケージごとの設定
2-4-6 デバッガでRPN計算機を実行
コラム ターミナルからデバッガを実行する
2-5 ツールチェインの補足情報
2-5-1 プラットフォーム・サポート・ティア
Tier 1
Tier 2
Tier 2.5
Tier 3
2-5-2 リリースサイクルとリリースチャネル
Nightlyチャネル
Betaチャネル
Stableチャネル
ポイントリリース
2-5-3 エディション
新エディションへの移行を支援するcargo fixコマンド
2-5-4 rustupのその他の機能
複数バージョンのRustツールチェインのインストールと管理
クロスコンパイル用ターゲットのインストール
その他の使い方
2-5-5 Cargoの主なコマンド
カスタムサブコマンド
第3章 クイックツアー
3-1 プログラムの概要
3-1-1 実行例
3-2 並列ソートに適したバイトニックソート
3-2-1 アルゴリズム
3-2-2 Pythonによるサンプル実装
3-2-3 Pythonプログラムの実行
3-3 第1段階:初歩的な実装
3-3-1 モジュール構成について
3-3-2 関数の引数を定義する
3-3-3 識別子の命名規則について
3-3-4 コーディング規約について
3-3-5 sort関数の本体を実装する
3-3-6 残りの関数を実装する
3-3-7 単体テストを書く(数値のソート)
3-4 第2段階:ジェネリクスでさまざまなデータ型に対応させる
3-4-1 テストケースを追加する(文字列のソート)
3-4-2 型パラメータを導入してジェネリクス化する
3-4-3 大小比較可能な型に限定する
3-4-4 コンパイラが型に関するバグを防いでくれる
3-4-5 列挙型で使いやすくする
3-4-6 match式による場合分け
3-4-7 エラーを返す
3-5 第3段階:クロージャでソート順をカスタマイズ
3-5-1 テストケースを追加する(学生データのソート)
3-5-2 クロージャの構文について
3-5-3 sort_by関数を実装する
3-5-4 クロージャの型について
3-5-5 既存の関数を修正する
3-5-6 トレイトを自動導出する
3-5-7 乱数で巨大なテストデータを生成する
3-5-8 イテレータチェインでスマートに
3-5-9 ソート結果を確認する
3-6 最終形:並列ソートの実現
3-6-1 標準ライブラリのマルチスレッドAPI
3-6-2 並列データ処理ライブラリRayon
3-6-3 Rayonを導入する
3-6-4 SyncトレイトとSendトレイト
Syncトレイト
Sendトレイト
3-6-5 所有権
3-6-6 sub_sort関数の並列化
3-7 仕上げ:ベンチマークプログラム
第4章 プリミティブ型
4-1 型の分類
コラム コードの表記法について
4-2 スカラ型
4-2-1 ユニット
4-2-2 真理値
4-2-3 固定精度の整数
ビット幅指定の整数型
アドレス幅の整数型
値の範囲
整数リテラル
代表的な整数演算
整数型のメソッドや定数
整数演算の桁あふれ
4-2-4 固定精度の浮動小数点数
4-2-5 文字
Unicodeスカラ値について
表示上の一文字とコードポイントの違い
4-2-6 参照
4-2-7 生ポインタ
4-2-8 関数ポインタ
コラム 関数ポインタとクロージャ
4-3 プリミティブな複合型
4-3-1 タプル
要素へのアクセス
4-3-2 配列
要素へのアクセス
スライスへの暗黙的な型強制
4-3-3 スライス
イミュータブルなスライスとミュータブルなスライス
スライスに対する主な操作
ボックス化されたスライス
4-3-4 文字列スライス
strの長さ
strと他の型の変換
可変のstr
第5章 ユーザ定義型
5-1 スタック領域とヒープ領域
5-2 標準ライブラリの主な型
5-2-1 Box(std::boxed::Box)
5-2-2 ベクタ(std::vec::Vec)
配列やスライスとの比較
5-2-3 その他のコレクション型
ハッシュアルゴリズムの性能
5-2-4 String(std::string::String)
to_string()とparse()
charやバイト列からStringへ
Stringとstrの比較
その他の文字列型
5-2-5 範囲(std::ops::Range)
5-2-6 オプション(std::option::Option)
5-2-7 リザルト(std::result::Result)
5-3 新しい型の定義と型エイリアス
5-3-1 型エイリアス
5-3-2 構造体(struct)
名前付きフィールド構造体
タプル構造体
ユニット構造体
5-3-3 列挙型(enum)
C言語風の列挙型
データを持つ列挙型
デフォルト値の設定について
5-3-4 構造体と列挙型のより詳しい情報
フィールドの可視性
フィールドに参照を持たせたい
ジェネリクス化
内部表現とrepr(C)
5-4 型変換
5-4-1 型キャスト
5-4-2 複合型の型変換
5-4-3 Transmute(std::mem::transmute)
5-4-4 型強制
型強制が行われる場所
推移的な作用
型強制の種類
Derefによる型強制
ポイントの弱体化
サイズの不定化
メソッドレシーバの型強制
第6章 基本構文
6-1 準備
6-1-1 パッケージの作成
6-1-2 パッケージの構造
6-2 コメント
6-3 うるう年と平年
6-4 use宣言
6-5 関数
6-5-1 関数定義
6-5-2 式と文
6-5-3 関数の実行
6-5-4 メソッド
6-5-5 関連関数
6-6 束縛とミュータビリティ
6-6-1 束縛とは
6-6-2 ミュータビリティ
6-6-3 スコープ
6-6-4 シャドウイング
6-6-5 定数とスタティック変数
定数
スタティック変数
6-7 演算子
6-8 分岐
6-8-1 if式
6-8-2 match式とパターン
match式の基本
網羅性の検査
パターン
6-8-3 if let式
6-9 繰り返し
6-9-1 loop式
6-9-2 while式
6-9-3 while let式
6-9-4 for式
6-10 クロージャ
6-11 アトリビュート
6-12 モジュールとアイテムの可視性
6-12-1 modキーワードとpubキーワード
6-12-2 モジュールをファイルとして切り出す
第7章 所有権システム
7-1 所有権システムの利点
7-1-1 ガベージコレクタが不要になる
7-1-2 メモリ安全性がコンパイル時に保証される
7-1-3 リソースの自動解放
7-2 所有権システムの概要
7-3 値の所有者
7-4 値のスコープ
コラム 値の破棄の意図的な遅延とリソースリーク
7-5 ムーブセマンティクス
7-6 コピーセマンティクス
7-6-1 Copyトレイトを実装する主な型
7-6-2 CopyトレイトとCloneトレイトの違い
7-7 借用:所有権を渡さずに値を貸し出す
7-8 参照のライフタイムと借用規則
7-8-1 新旧2種類の借用チェッカ
7-9 ライフタイムの詳細:簡単なベクタの実装
7-9-1 構造体の定義
7-9-2 new関連関数とwith_capacity関連関数
7-9-3 lenメソッドとcapacityメソッド
7-9-4 pushメソッドとgetメソッド
7-9-5 参照のライフタイムを確認する
7-9-6 ライフタイムの省略
7-9-7 staticライフタイム
7-9-8 popメソッドと借用からのムーブアウト
コラム 列挙型とnullableポインタ最適化
7-9-9 growメソッド
7-9-10 イテレータと所有権
7-9-11 可変の参照と不正なポインタの回避
7-9-12 構造体や列挙型のライフタイム
7-10 共同所有者を実現するポインタ:Rc型とArc型
7-10-1 循環参照の問題
7-11 内側のミュータビリティ
7-11-1 使用例:TLSとRefCellでスレッド固有の可変の値を持つ
7-11-2 使用例:RwLockで可変の値を複数スレッドで共有する
方法1:ArcとRwLockを組み合わせる
方法2:static変数とRwLockを組み合わせる
コラム アリーナ・アロケータ
7-12 クロージャと所有権
第8章 トレイトとポリモーフィズム
8-1 トレイトの基本
8-1-1 基本的な使い方
8-1-2 トレイト境界
コラム ジェネリクスの記法の表現力
8-1-3 トレイトの継承
8-1-4 デフォルト実装
8-1-5 トレイトとスコープ
8-1-6 トレイト実装のルール
8-1-7 自動導出
8-2 トレイトのジェネリクス
8-2-1 ジェネリクスの型パラメータと具体的な型
コラム トレイトとオーバーロードの関係
8-3 静的ディスパッチと動的ディスパッチ
8-3-1 ジェネリクスと静的ディスパッチのしくみ
8-3-2 トレイトオブジェクトと動的ディスパッチのしくみ
8-4 存在impl Trait
コラム 全称と存在
8-5 トレイトとアイテム
8-5-1 関連関数
8-5-2 関連定数
8-5-3 関連型
コラム ジェネリクスか関連型か
8-6 標準ライブラリのトレイト利用例
8-6-1 std::io::Write
8-6-2 std::convert::From
8-6-3 std::iter::Iterator
8-6-4 std::ops::Eq
8-6-5 std::os::unix::fs::FileExt
8-6-6 std::marker::Sized
8-7 演算子のオーバーロード
8-8 トレイトのテクニック
8-8-1 StringとInto
8-8-2 オプショナル引数
8-8-3 パスネーム
8-8-4 &strとstr
8-8-5 Newtypeによるトレイト実装制約の回避
8-8-6 列挙型を使った型の混合
第2部 実践編
第9章 パーサを作る
9-1 四則演算の処理系の作成
9-1-1 パーサを構成する要素
コラム パーサの種類
字句解析器
構文解析器
Rustで利用できるパーサコンビネータ
9-1-2 処理する計算式について
9-1-3 全体の設計
9-2 字句解析
9-2-1 トークン
トークンの種類
トークンの実装
9-2-2 字句解析器の実装
9-3 構文解析
9-3-1 抽象構文木の実装
抽象構文木とは
抽象構文木の実装
9-3-2 構文解析器の実装
9-3-3 エラー処理
構文エラーの出力
9-4 抽象構文木の利用
9-4-1 評価器の作成
9-4-2 コードの生成
第10章 パッケージを作る
10-1 コマンドラインツールの作成
10-1-1 Cargoとプロジェクト,パッケージ,クレート
10-1-2 マニフェストファイルの修正
10-1-3 プログラムの作成
10-1-4 ライブラリとバイナリへの分割
10-2 ドキュメントを書く
10-2-1 ドキュメントの構文
10-2-2 ドキュメントの書式
10-2-3 ドキュメント文章の記載
ドキュメントのビルド
コラム cargo docの便利なオプション
10-3 テストの追加
10-3-1 簡単なテストを書く
10-3-2 さまざまなテストを書く
Resultを返すテスト
パニックするテストを書く
時間がかかるテストを書く
その他のテクニック
10-3-3 テストを書く場所
プログラム中にテスト用のモジュールを書く
テスト専用のディレクトリを作成して書く
ドキュメント中に書く
コラム クレート内テストとクレート外テスト
10-4 パッケージを公開するために
10-4-1 パッケージのビルド
10-4-2 作業のコミット
コラム Cargo.lockはコミットすべき?
10-4-3 リモートリポジトリの追加
10-5 自動テストを行う
コラム CIのアレコレ
10-5-1 Travis CI
Travis CIの設定
Travis CIでのテスト
10-5-2 AppVeyor
AppVeyorの設定
AppVeyorでのテスト
コラム いろいろなCIサービス
10-6 パッケージをリリースする
10-6-1 マニフェストファイルの修正
10-6-2 最終確認
コラム パッケージ名の-と_
10-6-3 crates.io での公開
crates.ioへのユーザ登録とトークンの設定
パッケージのCLIからの公開
クレートのドキュメント
10-6-4 バイナリのリリース
第11章 Webアプリケーション,データベース接続
11-1 RustとWebの現状
11-1-1 同期と非同期
11-1-2 FuturesとTokio
11-1-3 Rustでの非同期の未来
11-1-4 Webアプリケーションフレームワーク
11-2 WebアプリケーションフレームワークActix Web
11-2-1 Hello, Actix Web
11-2-2 Actix Webとサーバの構成要素
ハンドラ
エクストラクタ
State
11-2-3 静的ファイルを返す
11-2-4 テンプレートを返す
11-3 JSON APIサーバ
11-3-1 仕様
11-3-2 ワークスペース
11-3-3 ひな型
11-3-4 データ型の定義
11-3-5 APIでの使用
11-4 Dieselを使ったデータベースの扱い
11-4-1 diesel_cliのインストール
11-4-2 スキーマ定義とマイグレーション
11-4-3 モデルの定義
11-4-4 Dieselを用いたクエリ
11-4-5 データベースへのコネクションとHTTPサーバへの統合
コラム Dieselの型とクエリキャッシュ
11-5 マルチパート/CSVファイルの扱い
11-6 CLIクライアントの作成
11-6-1 最初のコード
11-6-2 ReqwestによるHTTP POST
11-6-3 ReqwestによるHTTP GET
11-6-4 完成
第12章 FFI
12-1 C FFIの基本
12-1-1 単純なC FFI
12-1-2 ライブラリとのリンク
12-1-3 グローバル変数
12-1-4 静的リンクライブラリとのリンク
12-1-5 ビルドスクリプトサポート
コラム Rustのリンカ
12-2 Cのデータ型の扱い
12-2-1 プリミティブ型
12-2-2 ポインタ型
12-2-3 libc クレート
12-2-4 文字列型
12-2-5 関数ポインタ
12-2-6 所有権とリソースの解放
RustからC
コラム ValgrindをRustに使う
CからRust
12-2-7 Opaqueと空の列挙型
12-2-8 #[repr(C)]
コラム Nullableポインタ最適化
12-3 C APIの基本
12-3-1 プロジェクトの作成
12-3-2 ライブラリの作成
Cから呼び出す
12-4 実践C FFI
12-4-1 Onigmoのインストール
LinuxとmacOS
Windows MSVC
12-4-2 プロジェクト構成とbindgen
12-4-3 アンセーフなサンプルコード
12-4-4 ラッパ
索引
著者プロフィール