Rustの導入と入門

RustのWeb アプリケーションフレームワーク・ライブラリ
- actix-web
- Rocket
- warp
- Axum
- tide

Rustは、Rustのバージョンと関連するツールを管理する、rustup
というコマンドラインツールを使用してダウンロードする。
LinuxとmacOSでのrustupのインストール方法
$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
このコマンドはスクリプトをダウンロードし、rustupツールのインストールを開始し、Rustの最新の安定版をインストールする。
インストールがうまく行けば、以下の行が表示されるはずです。
Rust is installed now. Great!
To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).
To configure your current shell, run:
source "$HOME/.cargo/env"
以下を必ず実行してください。
$ source "$HOME/.cargo/env"
インストール完了後にシェルを再起動するか、上記のコマンドで環境設定を反映するとRustのコンパイル環境が有効になる。
Rustの開発環境において、全てのツールは~/.cargo/binディレクトリにインストールされます。ここに以下を含むRustのツールチェーンが置かれる。
- rustc
- cargo
- rustup
以下のコマンドで.cargo/bin
が表示されるはずです。
$ echo $PATH|grep cargo
以下のコマンドも成功するはずです。
$ rustc --version
Rustには3種類の配布用チャネルが用意されています。
- stable: 安定リリース版
- beta: 次期バージョンに向けたベータ版
- nightly: 開発版
rustup
コマンドを使ってインストールする。
$ rustup install stable

Rustビルドツールおよびパッケージマネージャ
Rustup
をインストールすると、Rustのビルドツール及びパッケージマネージャであるCargo
の最新安定版が同時に手に入ります。
- プロジェクトのビルドには
cargo build
- プロジェクトの実行には
cargo run
- プロジェクトのテストには
cargo test
- プロジェクトのドキュメントのビルドには
cargo doc
- ライブラリをcrates.ioに公開するには
cargo publish
RustとCargoがインストールされたことを確かめるには、ターミナルで以下を実行します。
$ cargo --version
VS CODEの公式サポートの拡張ツール

Hello, Worldを作成
cargo new
コマンドで新しいプロジェクトを作成します。
$ cargo new --bin hello-rust
これでhello-rust
という新しいディレクトリが作られ、以下のファイルが置かれる。
$ tree
.
├── Cargo.toml
└── src
└── main.rs
-
Cargo.toml :
Rust用のマニフェストファイル
で、プロジェクトの設定ファイル。プロジェクトのメタデータに加え依存関係も記録される。 -
src/main.rs : アプリケーションのコードを書く場所
cargo run
コマンドで実行する。
デフォルトでデバッグ用ビルドになるので、--release オプションを指定してリリース用ビルドにしてみる。
$ cargo run
Compiling hello-rust v0.1.0
Finished release [optimized] target(s) in 0.35s
Running `target/release/hello-rust`
Hello, world!
$ cargo run --release
Rust製のツールをインストール
プロジェクトの作成や実行で使用したcargo
の install コマンドを使うと、Rust製のツールを簡単にインストールできる。
以下は普段使っていて便利なRust製のツール
ripgrep
概要: 検索ツール。 grep みたいな感じです、とにかく速い
- インストール: cargo install ripgrep
- リポジトリ: GitHub - BurntSushi/ripgrep: ripgrep recursively searches directories for a regex pattern
exa
概要: ファイル列挙ツール、 ls みたいな感じです。ツリー表示できて便利
- インストール: cargo install exa
- リポジトリ: GitHub - ogham/exa: Replacement for 'ls' written in Rust.
fd
概要: ファイル検索ツール、 find みたいな感じです、これも速い
- インストール: cargo install fd-find
- リポジトリ: GitHub - sharkdp/fd: A simple, fast and user-friendly alternative to 'find'.

依存関係を追加する
アプリケーションに依存関係を追加します。
Rustのパッケージレジストリであるcrates.io上で、あらゆる種類のライブラリを見つけることができる。
Rustではパッケージのことをよくクレートと呼びます。
このプロジェクトでは、ferris-says
と呼ばれるクレートを使用します。
Cargo.tomlファイルにこの情報(クレートページから取得)を追加します。
[dependencies]
ferris-says = "0.2"
cargo build
上記のコマンドでCargoが依存関係をインストールします。
このコマンドの実行によってCargo.lock
という新しいファイルが作成されていることがわかる。
このファイルは私達がローカルで使っている依存関係の厳密なバージョンを記録しています。
この依存関係を使うためにmain.rs
を開いて以下の行を追加します。
use ferris_says::say;
この行はferris-says
クレートがエクスポートしたsay関数
を使えることを示しています。

Rustアプリケーションの初歩
新しい依存関係を持った小さなアプリケーションを書いてみます。
main.rsの中に、次のコードを追加します。
use ferris_says::say; // from the previous step
use std::io::{stdout, BufWriter};
fn main() {
let stdout = stdout();
let message = String::from("Hello fellow Rustaceans!");
let width = message.chars().count();
let mut writer = BufWriter::new(stdout.lock());
say(message.as_bytes(), width, &mut writer).unwrap();
}
以下のコマンドでアプリケーションを実行する。
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/hello-rust`
__________________________
< Hello fellow Rustaceans! >
--------------------------
\
\
_~^~^~_
\) / o o \ (/
'_ - _'
/ '-----' \

Rustの変数
Rustの変数は全てデフォルトではimmutable(不変)であるため、値の変更はできない。
# 以下はコンパイルエラーになる
let x = 100;
x = 200;
Rustでは、値を変更してはいけないのに変更できてしまう、それがバグのもとになると考えています。
もし、後から変数を変更したい場合は、mut
をつけます。こうすることで、変数はmutable型(可変)になり、後に変数の値を変更することが可能です。
# 以下はコンパイルエラーにならない
let mut x = 100;
println!("{}", x); // 100
x = 200;
println!("{}", x); // 200
データ型
Rustにはデータ型というものがあり、大きく分けて「スカラー型」と「複合型」があります。
スカラー型
- 整数型
- 浮動小数点型
- 論理値型
- 文字型
整数型
整数型は、小数点がない数値を表すデータ型です。
以下の通り、大きさと符号の有無に応じた6つの整数型があります。
大きさ | 符号付き | 符号なし |
---|---|---|
8bit | i8 | u8 |
16bit | i16 | u16 |
32bit | i32 | u32 |
64bit | i64 | u64 |
128bit | i128 | u128 |
アーキテクチャ依存 | isize | usize |
符号付き整数はi(integer)
で始まり、符号なし整数はu(unsigned)
で始まる。
大きさをbit数で続けます。
アーキテクチャ依存はisize
、usize
となります。
8bitから始まって128bitまでの整数を表すことができます。
また基準型というものがスカラー型にはあり、整数型ではi32が基準型になります。
浮動小数点型
小数値を表すデータ型です。
f32
とf64
があり、それぞれ32bit、64bitのサイズを持ち、基準型はf64です。
f32は単精度浮動小数点数、f64は倍精度浮動小数点数を表現する。
論理値型
論理値型は、真偽を表すデータ型です。
データ型はboolで、値はtrueとfalseしかとらない。
文字型
文字型は、文字を表すデータ型。
データ型はcharです。C/C++のcharも文字型ですが、これはASCIIコード(7bit)を表すのに対して、RustのcharはUnicodeを表す。
そのため日本語などの文字も表現できる。
基準型
整数型と浮動小数点型に基準型というのが出てきた。
基準型というのは、型注釈
のない変数宣言などで、優先して選択されるデータ型のことです。
例えば、以下のように整数型の変数x
を宣言したいとき、i32すなわち32bitの符号付き整数として宣言されたと見なされる。
浮動小数点型も同様で、以下ではf64が選択される。
let x = 10; // i32
let y = 3.14; // f64
型注釈
Rustでは、データ型を型注釈という形で指定します。上記の変数宣言を型注釈付きで示すと以下のようになる。
let x: i32 = 10;
let y: f64 = 3.14;
変数名の後にコロン(:)を続けて、その後にデータ型を記述する。
複合型
複合型とは、複数のスカラー型の値をまとめて扱うためのデータ型。
複合型には、以下の2つがある。
- タプル(tuple)
- 配列(array)
タプル型
タプル型は、複数のスカラー型の値をまとめて扱えるデータ型ですが、スカラー型がそれぞれ異なっていても扱うことができる。Pythonでも似たようなものがあります。
C/C++
における構造体のように見えるかも知れませんが、それぞれの値に名前はない。
let t = (2, 3.14, 0);
let (a, b, c) = t;
println!("a={}, b={}, c={}", a, b, c); // a=2, b=3.14, c=0
let x = t.0;
let y = t.1;
let z = t.2;
println!("x={}, y={}, z={}", x, y, z); // x=2, y=3.14, z=0
まず、タプル型の変数tを「2」「3.14」「0」という3つの値を持つように宣言している。
型注釈がないので、i32、f64、i32
がデータ型として選択される。
変数は1個なのに値が3つあります。これは他の変数群の初期化に用いたり、インデックスを用いて個別に取り出したりできる。
変数a, b, cにはtの値である2, 3.14, 0が入る。
変数x, y, zについても同様です。
個別に取り出す場合、インデックスは0から始まることに注意が必要。
これは、C/C++/Javaなどにおけるインデックスの考え方と同じであり、またインデックスは後述する配列と同様のチェックが行われて、範囲外のインデックスが指定された場合にエラーが発生する。
配列
配列型には、同じデータ型の値を複数持たせる
ことができる。
aは配列型で、i32がデータ型として選択
されます。
要素数は5個になります。参照も同様で、大かっこ([])にインデックスを入れて指定する。
let a = [1, 2, 3, 4, 5];
let x = a[0];
let y = a[1];
let z = a[2];
println!("x={}, y={}, z={}", x, y, z); // x=1, y=2, z=3
一度宣言した配列の要素数を変更することはできない。
この欠点を克服する手段として、コレクションライブラリ
が用意されています。
代表的なのはベクターです。