MENU

【Rust】変数と可変性について理解しよう!

この記事を読むのに必要な時間は約 8 分です。

前回に引き続きRustの基礎文法、備忘録になります。今回扱うのは変数。他の言語と違って癖があるのでしっかり抑えましょう。

扱う単元はこちら😻

まだ環境構築されていない方はこちらの記事をご参考ください。

環境構築無しでさくっと概要が知りたい方はWEB上のPlaygroud で作業することも可能です。DartPad 的なやつ。

ではいきましょう!

目次

Rustの変数は不変

不変変数

Rust の変数は普通に宣言すると不変 (値を書き換えられない) となっています。
変数の宣言には let を使います。

まずは下記のコードを自分の適当なプロジェクトファイルにコピって実行してみましょう。

fn main() {
    let x = 5; //値の宣言はlet を使用。
    println!("The value of x is: {}", x);     // xの値は{}です
    x = 6; //x の値を書き換えてみる
    println!("The value of x is: {}", x);
}

実行結果は下記のようになります。

error[E0384]: cannot assgin twice immutable variable `x`
              (不変変数`x`に2回代入できません)
 --> src/main.rs:4:5
  |
2 |     let x = 5;
  |         - first assignment to `x`
  |         (`x`への最初の代入)
3 |     println!("The value of x is: {}", x);
4 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable

このようにコンパイルエラーになります。

一番下の行にある通り不変の変数に値を再代入することはできません。

値が不変であるということをコンパイラが担保してくれるため、値が変化しているかを追いかける必要がなくなり、コードを通して正しいことを確認するのが簡単になるというメリットがあります。

可変変数

とはいえ可変変数として宣言したいときもあります。
そんなときはlet に mut をつけて宣言しましょう。

fn main() {
    let mut 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 (file:///projects/variables)
    Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs
     Running `target/debug/variables`
The value of x is: 5   (xの値は5です)
The value of x is: 6

変数と定数

値を不変にするといえば定数ですよね。
不変変数と定数は同じ不変とはいえ用途、用法が異なります。定数の特徴は次の通り。

・定数にはmutキーワードは使えない。
constキーワードで宣言し、値の型は必ず注釈する。
・グローバルスコープを含め、定数はどんなスコープでも定義できる。
・定数は定数式にしかセットできない。
つまり、関数呼び出し結果や、実行時に評価される値にはセットできない。
・全て大文字でアンダースコアで単語区切りする

こんなところでしょうか。

実際のプログラムを見てみましょう。

fn main() {
const MAX_POINTS: u32 = 100_000;
  ///...
}

こんな感じで宣言します。
定数として宣言して使い回せば、変更を加えたいときなどに一箇所変更すれば済むので便利ですよね。

シャドーイング

実はRustでは一度宣言した変数再度 let で宣言することができます。

これをシャドーイングといい、先に宣言していた変数をあとで宣言した変数で覆い隠して新しい変数を宣言しているというニュアンスになります。

これは結構特殊ですよね。コードを見てみましょう。

fn main() {
    let x = 5;

    let x = x + 1;

    let x = x * 2;

    println!("The value of x is: {}", x);
}

実行結果

$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
    Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs
     Running `target/debug/variables`
The value of x is: 12

ここでは初めに5を代入したx を再定義し、元のxに1 を加えて覆い隠す… ということをしています。

mut との違いは let なしで値を上書きしようとするとコンパイルエラーになることです。
シャドーイングではあくまで「不変変数を覆い隠して再定義するもの」なのでlet がないと再定義できていないことになります。

以下の例ではコンパイルエラーになりますね。

fn main() {
    let x = 5;

    x = x + 1;

    println!("The value of x is: {}", x);
}

mut とシャドーイングのもう一つの違いは、値の型を変えつつ、同じ変数名を使いまわせることです。

下記の例ではlet により変数を再定義しているので型が変わっていてもエラーは起きません。

let spaces = "   ";
let spaces = spaces.len();

一方下記の例ではlet mut で可変変数として定義したものに数値型を代入しようとしているのでエラーです。

let mut spaces = "   ";
spaces = spaces.len();

シャドーイングは変数を再定義しているのだと理解できれば簡単ですね。

今回はここまでです!また次回!

カテゴリー

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次