書籍概要

実践Rust入門
[言語仕様から開発手法まで]

著者
発売日
更新日

概要

Rustは2015年に安定版がリリースされた新しい言語です。静的型付けと関数型言語などにみられる高度な抽象化のしくみを取り入れており,高品質で再利用性の高いプログラムを開発できます。さらに,ハードウェア資源についてC/C++と同等の効率の良い制御ができますが,決定的に違うのは,安全性をかなり重視しています。つまりRustは開発者の生産性を高めつつ,性能やハードウェア資源の効率を最大限に発揮するという,従来の言語では相反する要件を同時に満たす,数少ないプログラミング言語の1つなのです。本書はこの注目のプログラミング言語Rustの入門書です。この1冊でRustの言語仕様から開発現場で必要となる知識までを丁寧に解説しています。

こんな方におすすめ

  • Rustをはじめてみたい方

目次

第1部 基礎編
第1章 Rustの特徴

  • 1-1 Rustの特徴
  • 1-2 最も愛されている言語
  • 1-3 Rustの起源
  • コラム 名前の由来
  • 1-4 なぜRustなのか?
    • 1-4-1 トップクラスのパフォーマンス
    • 1-4-2 安全なシステムプログラミング言語
    • 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

第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 プログラムの内容
  • 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 プログラムの作成
    • コラム ジェネリクスにおけるトレイト境界について
    • 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 プラットフォーム・サポート・ティア
    • 2-5-2 リリースサイクルとリリースチャネル
    • 2-5-3 エディション
    • 2-5-4 rustupのその他の機能
    • 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トレイト
    • 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 文字
    • 4-2-6 参照
    • 4-2-7 生ポインタ
    • 4-2-8 関数ポインタ
    • コラム 関数ポインタとクロージャ
  • 4-3 プリミティブな複合型
    • 4-3-1 タプル
    • 4-3-2 配列
    • 4-3-3 スライス
    • 4-3-4 文字列スライス

第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)
    • 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)
    • 5-3-4 構造体と列挙型のより詳しい情報
  • 5-4 型変換
    • 5-4-1 型キャスト
    • 5-4-2 複合型の型変換
    • 5-4-3 Transmute(std::mem::transmute)
    • 5-4-4 型強制

第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式とパターン
    • 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で可変の値を複数スレッドで共有する
    • コラム アリーナ・アロケータ
  • 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 パーサを構成する要素
    • コラム パーサの種類
    • 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 さまざまなテストを書く
    • 10-3-3 テストを書く場所
    • コラム クレート内テストとクレート外テスト
  • 10-4 パッケージを公開するために
    • 10-4-1 パッケージのビルド
    • 10-4-2 作業のコミット
    • コラム Cargo.lockはコミットすべき?
    • 10-4-3 リモートリポジトリの追加
  • 10-5 自動テストを行う
    • コラム CIのアレコレ
    • 10-5-1 Travis CI
    • 10-5-2 AppVeyor
    • コラム いろいろなCIサービス
  • 10-6 パッケージをリリースする
    • 10-6-1 マニフェストファイルの修正
    • 10-6-2 最終確認
    • コラム パッケージ名の-と_
    • 10-6-3 crates.io での公開
    • 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とサーバの構成要素
    • 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 所有権とリソースの解放
    • コラム ValgrindをRustに使う
    • 12-2-7 Opaqueと空の列挙型
    • 12-2-8 #[repr(C)]
    • コラム Nullableポインタ最適化
  • 12-3 C APIの基本
    • 12-3-1 プロジェクトの作成
    • 12-3-2 ライブラリの作成
  • 12-4 実践C FFI
    • 12-4-1 Onigmoのインストール
    • 12-4-2 プロジェクト構成とbindgen
    • 12-4-3 アンセーフなサンプルコード
    • 12-4-4 ラッパ

サポート

正誤表

本書の以下の部分に誤りがありました。ここに訂正するとともに,ご迷惑をおかけしたことを深くお詫び申し上げます。

(2021年12月22日最終更新)

P.150 本文3行目

ビット演算のnotは~を使います。
ビット演算のnotは!を使います。

P.150 表4.2

ビットごとの否定 (not) ~
ビットごとの否定 (not) !

(以下2019年5月20日更新)

P.92 2段落目

一方でバイトニックソートは計算量が .. 常にO(n log n)です。
一方でバイトニックソートは計算量が .. 常にO(n log^2 n)です。

P.92 2段落目

全行程の並列処理が可能で、その場合はO(log n)の時間でソートできます
全行程の並列処理が可能で、その場合はO(log^2 n)の時間でソートできます

P.94 7行目

ステップ3bでは
ステップ2cでは

P.107 ch3/biotonic-sorter/src/second.rs


let mut x = vec!["Rust", "is", "a", "system", "programming", "language",
"that", "runs"];


let mut x = vec!["Rust", "is", "fast", "and", "memory-efficient",
"with", "no", "GC"];

P.120 ch3/biotonic-sorter/src/third.rs


use super::{is_power_of_two, sort, sort_by};


use super::{sort, sort_by};

P.123 ch3/biotonic-sorter/src/third.rs


if is_power_of_two(x.len()) {


if x.len().is_power_of_two() {

P.132 コードブロック31行目


let sum = (1.. = n).sum();


let sum = (1..=n).sum();

P.150 表4.2 整数型がサポートしている主な演算の「算術演算」

加算、除算、..
加算、減算、..

P.181 図5.3 左上

capacity 5
capacity 8

P.181 図5.3 左上

vec
Vec

P.259 図7.1図の右

直前の状態
の状態

P.284 図7.10

「所有する」の矢印の方向が下の箱に向かっている
「所有する」の矢印の方向は「100」、「200」の箱に向かう

P.370 ch9/parser/src/main.rsの12行目に以下を追加


use std::iter::Peekable;

P.380 ch9/parser/src/main.rs(抜粋)の1行目に以下を追加


use std::str::FromStr;

P.382 ch9/parser/src/main.rs(抜粋)の26行目


let loc = &self.1


let loc = &self.loc

P.382 ch9/parser/src/main.rs(抜粋)の27行目


match self.0


match self.value

P.382 ch9/parser/src/main.rs(抜粋)の38,40,41,45行目


tok.kind


tok.value

P.385 ch9/parser/src/main.rs(抜粋)の16行目


e.1.clone()


e.loc.clone()

P.393 ch9/parser/src/main.rs(上)の2行目


use self::Ast::*;


use self::AstKind::*;

P.393 ch9/parser/src/main.rs(下)の9行目


use self::BinOp::*;


use self::BinOpKind::*;

P.456 2つ目のコードブロック先頭に以下を追加


use actix_web::State;

P.526 ch12/onigmo-rs/onigmo-sys/build.rs

以下のURLより差分をご確認ください。

P.535 ch12/onigmo-rs/onigmo/src/lib.rs(抜粋)の14行目


num_regs = (*self.0).num_regs


num_regs = (*self.as_ptr()).num_regs

P.535 ch12/onigmo-rs/onigmo/src/lib.rs(抜粋)の14行目


let region = *(self.0).0;


let region = *(self.0).as_ptr();

P.536 ch12/onigmo-rs/onigmo/examples/simple.rs(抜粋)の4行目


"a(.*)b|[e-f]+".to_string()


"a(.*)b|[e-f]+"

商品一覧