安全性、速度、並行性を兼ね備えた言語と、巷でうわさの「Rust」を覗いてみる(その2)
前回の記事「安全性、速度、並行性を兼ね備えた言語と、巷でうわさの「Rust」を覗いてみる(その1)」に続き、今回は「The Rust Programming Language」を読みながら、変数の部分を覗いていきたいと思います。
変数は基本的にイミュータブル
まずは、文字列を出力する単純なコードを書きます。
1 2 3 4 5 |
fn main() { let name = "foo"; println!("{}", name); } |
println! の最後の「!」はマクロを表し、第一引数の「{}」はプレースホルダらしいです。
Rustは、明示的に「mut」をつけないと再代入不可能とのことなので、
1 2 3 4 5 6 7 |
fn main() { let name = "foo"; println!("{}", name); name = "bar"; println!("{}", name); } |
むりやりnameに再代入してコンパイルすると・・・。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ cargo run Compiling hello-rust v0.1.0 (/home/*****/github.com/*****/hello-rust) error[E0384]: cannot assign twice to immutable variable `name` --> src/main.rs:5:5 | 2 | let name = "foo"; | ---- | | | first assignment to `name` | help: consider making this binding mutable: `mut name` ... 5 | name = "bar"; | ^^^^^^^^^^^^ cannot assign twice to immutable variable For more information about this error, try `rustc --explain E0384`. |
想定通り怒られます。
変数をミュータブルにする
mut をつけて変更可能にしてみます。
1 2 3 4 5 6 7 |
fn main() { let mut name = "foo"; println!("{}", name); // foo name = "bar"; println!("{}", name); // bar } |
note: mutをいつ使うのか
考えるべきトレードオフはバグの予防以外にも、いくつかあります。例えば、大きなデータ構造を使う場合などです。 インスタンスを可変にして変更できるようにする方が、いちいちインスタンスをコピーして新しくメモリ割り当てされたインスタンスを返すよりも速くなります。 小規模なデータ構造なら、新規インスタンスを生成して、もっと関数型っぽいコードを書く方が通して考えやすくなるため、 低パフォーマンスは、その簡潔性を得るのに足りうるペナルティになるかもしれません。The Rust Programming Language 日本語版
このように書かれています。
基本的にはmutを付けずに関数型プログラミングスタイルで記述し、 パフォーマンスが気になる箇所はmutを付ける運用にするのが良さそうです。
シャドーイング
mut は、変数を可変にしますが、シャドーイングは変数を新しく生成して上書きします。
1 2 3 4 5 6 7 |
fn main() { let name = "foo"; println!("{}", name); // foo let name = "bar"; println!("{}", name); // bar } |
1 2 3 4 5 6 7 |
fn main() { let name = "foo"; println!("{}", name); // foo let name = 1; println!("{}", name); // 1 } |
ブロックとスコープと凍結(Freezing)
最後に、ブロックとスコープを確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
fn main() { let name = "foo"; println!("{}", name); // foo { println!("{}", name); // foo let name = 1; println!("{}", name); // 1 } println!("{}", name); // foo } |
ブロック内でシャドーイングしていますが、ブロックを抜けると元の値にもどってることが確認できます。
これらを使って、 mut の変数をブロック内で変更不能にしてみます。
1 2 3 4 5 6 7 8 |
fn main() { let mut name = "foo"; { let name = name; name = "bar"; // error } } |
ブロックの中で mut の変数を mut 無しでシャドーイングすることで、 そのスコープ内で変数を凍結(Freezing)できます。
The following two tabs change content below.

tkr2f
事業開発部 web application engineer
2008年にアーティスへ入社。
システムエンジニアとして、SI案件のシステム開発に携わる。
その後、事業開発部の立ち上げから自社サービスの開発、保守をメインに従事。
ドメイン駆動設計(DDD)を中心にドメインを重視しながら、保守可能なソフトウェア開発を探求している。

最新記事 by tkr2f (全て見る)
- 安全性、速度、並行性を兼ね備えた言語と、巷でうわさの「Rust」を覗いてみる(その2) - 2022年4月19日
- 安全性、速度、並行性を兼ね備えた言語と、巷でうわさの「Rust」を覗いてみる(その1) - 2022年3月8日
- database/sqlのrowsのメモリ量を調査する - 2021年12月8日
- Golangでデッドロックを作って遊んでみる~並行処理でデッドロックを起こさないために~ - 2021年10月7日
- <Goのパッケージ放浪記> ioパッケージに定義されている「Closerインターフェイス」について - 2021年3月18日
RECOMMENDED
関連記事
NEW POSTS
最新記事
FOLLOW US
最新の情報をお届けします
- facebookでフォロー
- Twitterでフォロー
- Feedlyでフォロー