Rust 入門
〜第1回〜
Rustとは
開発
- 開始
- 2006年
- 初期開発者
- Graydon Hoare
-
正式プロジェクト開始
- 2009年(Mozilla社にて)
- 安定版リリース
- 2015年
- システムプログラミング言語
-
ゴール
- 速度、安全性、並行性
最も愛されている開発言語(2019年)
利用企業例
- Discord
- 読み取り状態情報を保存するのに使うデータ構造で利用(Read State)
- https://blog.discord.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f
- Dropbox
- Amazon Web Servise
- 「Firecracker」サーバーレス運用モデルを提供するセキュアなマルチテナントコンテナおよび機能ベースのサービスの作成と管理を目的としたオープンソースの仮想化技術
- https://github.com/firecracker-microvm/firecracker
Hello, World!
Hello, Cargo!
※Rust そのもののインストールはやらないよ
コンパイルと実行
fn main() {
println!("Hello, world!");
}
1. main.rsを作成
2. コンパイルと実行
$ rustc main.rs
$ ./main
Hello, world!
自動フォーマッター
$ rustfmt --check main.rs
Diff in /Users/hironori/work/learn-rust-programming/hello_world/main.rs at line 1:
fn main() {
- println!("Hello, world!");
+ println!("Hello, world!");
}
$ rustfmt main.rs
- 空白を削除してみて --check オプションで変更されることを確認
- 実際にフォーマット変更
Cargo
- ビルドシステムおよびパッケージマネージャー
- コードに依存関係が必要なライブラリを呼び出す
プロジェクトの作成
$ cargo new hello_cargo
TOMLファイル
$ cat Cargo.toml
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["hirontan <hirontan@sora.flights>"]
edition = "2018"
[dependencies]
-
package:ステートメント
- 名前、バージョン、作成者、使用するエディションの記載
-
dependencies:プロジェクトの依存関係リスト
- コードのパッケージはクレートと呼ばれる
Cargo について補足
- ソースファイルがsrcディレクトリ内にある
- 最上位のプロジェクトディレクトリは、READMEファイル、
ライセンス情報、構成ファイル、およびコードに関係のないものである - Cargoを利用しないプロジェクトで始めた場合、
ソースコードをsrcディレクトリに置き直し、TOMLファイルを作成する
$ tree
.
├── Cargo.lock
├── Cargo.toml
└── src
└── main.rs
ビルドと実行
$ cargo build
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
ビルド
- target/debug/hello_cargo に実行ファイルができる
- Cargo.lock ファイルができ、依存関係を記載してくれる
実行
$ ./target/debug/hello_cargo
Hello, world!
ワンコマンドで!
$ cargo run
おまけ
$ cargo build --release
-
target/release 配下にファイルが
できる - 最適化によりコード実行が高速になる
かわりに、コンパイルに時間がかかる - 実行時間のベンチマークをする場合、
target/release の実行ファイルを
実行する
$ cargo check
コンパイルのみ実行
リリース用ビルド
- 実行ファイルは生成されない
Rustの特徴(一部)
3章までの話まで
変数のデフォルトがimmutable
// src/main.rs
fn main() {
let x = 5;
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
}
$ cargo run
Compiling variables v0.1.0
error[E0384]: cannot assign twice to immutable variable `x`
--> src/main.rs:4:5
|
2 | let x = 5;
| -
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
3 | println!("The value of x is: {}", x);
4 | x = 6;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0384`.
error: could not compile `variables`.
To learn more, run the command again with --verbose.
コード
実行
- 不変変数x(immutable)に2回代入してはならない
- コンパイル時にエラーが出る
- 値の変化しない変数はわかるようになる
mutableにしたい場合、
let mut キーワードを利用する
ステートメントは値を返さない
- letステートメントを別の変数に割り当てることはできません
- CやRubyなどでは、x = y = 6 で x と y 両方に 6 を割り当てられるが、
Rustは割り当てられない
fn main() {
let x = (let y = 6); # → letステートメントで別の変数を割り当てている。Rustではエラーになる。
}
ブロック{}はletステートメントで扱える
fn main() {
let y = {
let x = 3;
x + 1
};
}
- 最後の式を暗黙的に返す
戻り値を持つ関数は、-> の後に型を宣言
fn main() {
plus_one(5);
}
fn plus_one(x: i32) -> i32 {
x + 1
}
メモリの開放について
- 従来
- ガベージコレクター(GC)を備えた言語では、GCは追跡し、使用されなくなったメモリをクリーンアップするため、考える必要はない
- GCがなければ、メモリが使用されなくなったときを識別し、コードを呼び出して明示的に行う必要がある
- 歴史的に難しいプログラミング問題
- 忘れてしまうとメモリを無駄にする
- 早すぎると、変数が無効になる
- 1つの割り当てと1つの空きをペアにする必要がある
- Rust
- メモリを所有する変数がスコープ外になると、メモリは自動的に返される
{
let s = String::from("hello"); // s is valid from this point forward
println!("{}", s);
} // this scope is now over, and s is no longer valid
Appendix
変数と定数の違い
- 定数
- mutを定数とともに使用することは許可されてない
- 定数はデフォルトでは不変であるだけでなく、常に不変
- letの代わりにconstキーワードを使用して定数を宣言
- 値の型に注釈を付ける必要がある
- 定数の命名規則は、大文字 + アンダースコアで構成
const MAX_POINTS: u32 = 100_000;
fn main() {
let mut x = 5;
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
println!("The value of MAX_POINTS is: {}", MAX_POINTS);
}
次回、所有権を
レクチャーできればと!
Rust 入門〜第1回〜
By hirontan
Rust 入門〜第1回〜
- 251