Rustはメモリ安全、スレッド安全を保ちつつ、高パフォーマンスなプログラムを開発できるプログラミング言語です。また、手続き型、オブジェクト指向型、関数型でのプログラミングに対応できるマルチパラダイムの言語でもあります。ただ、そういったRustのポテンシャルを引き出すには、所有権やライフタイム、ジェネリクスやトレイトといった特徴的な仕様の理解が求められ、これらは初学者の壁にもなっています。本書ではそれら難解な仕様をピックアップし、他のプログラミング言語とコードレベルで比較しながら、「なぜそのような仕様になっているか」という言語のコンセプトからRustの理解を試みます。加えて、Rustのこまやかなエラーメッセージを読みつつ、Rustをうまく書くための知識もお伝えします。
■■■第1章 Rustを学ぶにあたって
■■1.1 Rustの特徴
■パフォーマンスと信頼性
■生産性
■そのほかの特徴
■■1.2 Rustの効率的な学習法
■■1.3 Rustの情報源・利用可能なリソース
■The Rust Programming Language(The book)
■Rust By Example
■標準ライブラリのドキュメント
■Webサイト「crates.io」
■The Rust Reference
■Rust Playground
■■■第2章 Rustをはじめよう
■■2.1 Rustの開発環境のインストール
■■2.2 Rustでコードを書いてみよう
■cargo newによるパッケージディレクトリの作成
■自動作成されるサンプルプログラムのコンパイル・実行
■「最初のコード」とその実行
■Rustの記法・特徴的な書き方
■■2.3 Rustのコンパイルエラーメッセージ
■■2.4 テストの実装
■■2.5 クレートとモジュール
■バイナリクレートとライブラリクレート
■ソースコードの分割とモジュール
■crates.io
■■2.6 高機能エディタVisual Studio Codeの導入
■RustのコーディングをVS Codeで行うには
■Rustでの開発に便利な拡張機能
■clippyを使う
■■■第3章 所有権とライフタイム
■■3.1 Rustにおける変数への値の割り当て
■イミュータブルとミュータブル
■型推論
■■3.2 「束縛」の描像から見た、変数への値の割り当て
■C言語における変数・値とメモリ
■Pythonにおける変数と値の結び付け
■■3.3 Rustにおける変数の束縛と所有権
■コピーセマンティクス
■ムーブセマンティクス
■関数の引数への引き渡しによる所有権の移動、コピー
■■3.4 リファレンス
■リファレンスによる所有権の借用
■リファレンスのスコープ
■ライフタイムとリファレンス
■関数定義におけるライフタイムパラメータ
■リファレンスのルールのまとめ
■関数の引数を値にするか、リファレンスにするか
■■3.5 変数の再宣言とシャドーイング
■■3.6 所有権とメモリ安全性
■メモリ管理の難しさ
■Rustのメモリ管理
■■■第4章 Rustにおける値の型
■■4.1 静的型付け言語と動的型付け言語
■■4.2 プリミティブ型
■■4.3 整数型・浮動小数点型
■型が異なる2つの整数の間の四則演算はできるか?
■整数の除算について
■■4.4 配列・タプル・スライス・ベクター
■配列
■タプル
■スライス
■ベクター型
■■4.5 文字・文字列の型
■文字型
■文字列型
■String型
■■4.6 構造体
■構造体の宣言
■構造体のインスタンスの作成
■構造体のフィールドにアクセスするときの自動的なデリファレンス
■フィールド名と同じ変数がスコープの中にある場合の構造体インスタンスの作成
■同じ型の既存の構造体の一部フィールドの書き換えによる構造体インスタンスの作成
■タプル構造体
■Unit-Like構造体
■構造体へのメソッドの実装
■構造体、フィールド、メソッドの隠蔽
■Debugトレイトの実装
■Copyトレイトの実装
■構造体のフィールドにリファレンスを使う場合
■■4.7 列挙型
■単純な列挙型
■列挙型におけるmatchの活用
■列挙子にデータを持たせた列挙型
■■4.8 Option T 型
■Option T 型の必要性
■Option T 型の定義
■Option T 型の値の生成
■Option T 型の値の処理
■■4.9 エラーハンドリングとResult T, E 型
■エラーハンドリングのパターン
■RustにおけるResult T, E 型によるエラーハンドリング
■■4.10 match式とif let
■match式
■if let
■■4.11 そのほかの便利な型
■HashMap K, V
■JSONを扱うserdeのValue型
■■4.12 メモリへの値の配置
■生ポインタ
■メモリの領域
■Vec型のデータはどこに置かれるか?
■Box T 型
■constとstatic
■■4.13 Rc T 型・RefCell T 型・Weak T 型
■関数内の自動変数は関数の外では使えない
■C言語で関数の外で値を共有するにはヒープ領域に配置する
■Rc T 型
■Rc T 型を使って共通の値を所有権付きで参照する
■RefCell T 型
■Rc T 型の循環参照問題
■Weak T 型によるノード間の弱結合
■■■第5章 Rustの抽象化プログラミング
■■5.1 Rustにおける抽象化
■■5.2 ジェネリクス
■■5.3 ジェネリクスの型に対するトレイトによる制約
■トレイトの定義と実装
■トレイトによる型パラメータへの制約(トレイト境界)
■トレイトによる動作の追加実装と型の分類
■メソッドのデフォルト実装
■C++の型テンプレートとの比較
■■5.4 既存のトレイトの新しい型への実装
■■5.5 トレイトの関連型
■トレイトの関連型の必要性
■トレイトのデフォルト実装の活用
■■5.6 クラスによる抽象化との比較
■継承を使ったC++のコード例
■トレイトを活用したRustでの実装
■新しい動作をC++のコードに追加する
■新しい動作をRustのコードに追加する
■■5.7 トレイトオブジェクト
■実行時に決まるエラーの型
■異なる型を要素とするVec T 型
■■5.8 抽象返却値型
■トレイトオブジェクトによる抽象返却値型
■impl Traitによる抽象返却値型
■■5.9 静的・動的ディスパッチとゼロコスト抽象化
■■5.10 トレイトに関するトピックス
■println!
■Derefトレイト
■デリファレンス型強制
■■5.11 トレイトに関する情報源
■■■第6章 ファイルやソケットの入出力
■■6.1 ファイルの入出力
■ファイルの内容を固定長のバッファに繰り返し読み出す
■BufReaderを使って1行ずつ読み出す
■モジュール化
■バイナリファイルを読み出す
■ファイルの書き込み
■ファイルを開く際のオプションの指定
■■6.2 ソケットの入出力
■■■第7章 Rustの関数型プログラミング向けの機能
■■7.1 関数型プログラミングとは?
■■7.2 イテレータ
■レンジ
■IntoIteratorトレイト
■Vec T 型に対するイテレータ
■iter()とiter_mut()
■Rustでのforループ
■collect()
■■7.3 再帰関数
■■7.4 関数を引数とする関数
■map()
■filter()、fold()、reduce()
■■7.5 関数を返却する関数
■所有権が最初の呼び出しで消費されてしまうクロージャ(FnOnceの利用)
■クロージャに閉じ込められた環境の変数を変更する場合(FnMutの利用)
■■7.6 パターンマッチの活用
■■■第8章 Rustによるスレッド・非同期プログラミング
■■8.1 スレッドによる並列実行と非同期処理による同時実行
■■8.2 スレッドによる並列実行
■スレッドによる並列実行を活用したベクターの要素の和の計算
■スレッド間での共有データを参照するには
■スレッド間での共有データに書き込みをするには
■メインスレッドとの通信
■ソケットの入出力を使ったエコーサーバ
■■8.3 非同期処理による同時実行
■JavaScriptにおける非同期関数
■Rustにおける非同期処理
■非同期タスクのランタイムによる実行
■非同期関数の同時実行
■非同期関数を用いたエコーサーバ
■■■第9章 C言語のライブラリのRustからの利用
■■9.1 C言語で書かれたzlibの関数のRustからの呼び出し
■■9.2 呼び出す外部関数の引数が構造体である場合
■■9.3 自作のC言語のコードをRustのコードとリンクする