【Rust】変数、定数、シャドーイング

1. 概要

今回はRustの変数、定数、シャドーイングについて学んでいきたいと思います。

2. 変数

Rustで変数を定義するには、「let 変数名: 型 = 値;」と書きます。

では、実際の変数を定義し、定義した変数を出力するプログラムを書いていきます。

fn main() {
    let x: i32 = 5; // ←変数を定義する。
    println!("x = {}", x);     // xの値は{}です。
}

実行します。

cargo run

結果

Compiling hello_rust v0.1.0 (<作業ディレクトリ>/hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.47s
     Running `target/debug/hello_rust`
x = 5

println!の{}の中の変数xに束縛した値が表示されます。

println!は関数ではなくマクロと言います。そして、マクロとして定義されているものは、末尾に「!」がついています。

他のプログラミング言語では、前処理やプリプロセッサなどと呼ばれる機能で、コンパイルするときにソースコードの一部を置き換える働きをします。

複雑な記述が必要な場合でも、マクロを使用すると短く記述することができます。

マクロの詳細については、また今度学んでいきたいと思います。

また、Rustでは変数を定義することを値を変数に束縛すると言います。

Rustは変数を定義する際、デフォルトがイミュータブル(不変)なので、変数を定義した後に値を変更するとエラーになります。

fn main() {
    let x: i32 = 5; // ←変数を定義する。
    println!("x = {}", x); // xの値は{}です。

    x = 6; // 値を変更する。
    println!("x = {}", x); // xの値は{}です。
}

実行します。

cargo run

結果

Compiling hello_rust v0.1.0 (<作業ディレクトリ>/hello_rust)
error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:5:5
  |
2 |     let x = 5; // ←変数を定義する。
  |         -
  |         |
  |         first assignment to `x`
  |         help: consider making this binding mutable: `mut x`
...
5 |     x = 6; // 値を変更する。
  |     ^^^^^ cannot assign twice to immutable variable

For more information about this error, try `rustc --explain E0384`.
error: could not compile `hello_rust` due to previous error

イミュータブルな変数を変更しようとしているので、エラーになりました。

変数の値を変更したい場合は、変数がミュータブル(可変)であることを明示的にしなければなりません。

ミュータブルな変数を定義するには、「let mut 変数名: 型 = 値;」と書きます。

fn main() {
    let mut x: i32 = 5; // ←ミュータブルな変数を定義する。
    println!("x = {}", x); // xの値は{}です。

    x = 6; // 値を変更する。
    println!("x = {}", x); // xの値は{}です。
}

実行します。

cargo run

結果

Compiling hello_rust v0.1.0 (<作業ディレクトリ>/hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.36s
     Running `target/debug/hello_rust`
x = 5
x = 6

変数xをミュータブルで定義したので今回はエラーにならず実行できました。

ちなみに、Rustは型推論があるので変数を定義するときに、明示的に型を指定する必要はありません。

fn main() {
    let x = 5; // ←変数を定義する。
    println!("x = {}", x);     // xの値は{}です。
}

実行します。

cargo run

結果

Compiling hello_rust v0.1.0 (<作業ディレクトリ>/hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.47s
     Running `target/debug/hello_rust`
x = 5

問題なく実行できることが確認できました。

3. 定数

Rustで定数を定義するには、「const 定数名: 型 = 値;」と書きます。

また、変数を定義するときは型推論があるので型は省略可能でしたが、定数は明示的に型を指定しなければいけません。

では、実際の変数を定義し、定義した変数を出力するプログラムを書いていきます。

// 定数を定義
const MIN_VALUE: i32 = 0;
const MAX_VALUE: i32 = 100;

fn main() {
    // 定義した定数を出力
    println!("最小値 = {}", MIN_VALUE);
    println!("最大値 = {}", MAX_VALUE);
}

実行します。

cargo run

結果

Finished dev [unoptimized + debuginfo] target(s) in 0.03s
     Running `target/debug/hello_rust`
最小値 = 0
最大値 = 100

4. シャドーイング

シャドーイングとは同一スコープ内で同じ変数を定義して、それ以前に宣言した変数を覆い隠し、後に宣言した変数を参照します。

例えば、文字列の一部を置換し、置換後の文字列だけを使うプログラムを書きます。

fn main() {
    // 変数の定義
    let s1 = "Hello World";

    // 文字列の一部を置換
    let s2 = s1.replace("World", "Rust");

    // 置換後の文字列を表示
    println!("{}", s2);
}

実行します。

cargo run

結果

Compiling hello_rust v0.1.0 (<作業ディレクトリ>/hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.51s
     Running `target/debug/hello_rust`
Hello Rust

置換後の文字列だけを使用したいので、変数s1の一部を置換した値を変数s2に束縛しています。

ただ、置換するたびに変数を定義していては面倒ですし、可読性も落ちます。

こういった場合に、シャドーイングを使用します。

fn main() {
    // 変数の定義
    let s = "Hello World";

    // シャドーイングを使って、文字列の一部を置換
    let s = s.replace("World", "Rust");

    // 置換後の文字列を表示
    println!("{}", s);
}

実行します。

cargo run

結果

Compiling hello_rust v0.1.0 (<作業ディレクトリ>/hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.79s
     Running `target/debug/hello_rust`
Hello Rust

問題なく実行できました。

シャドーイングはちょっとした用途で使用する似たような名前の変数を定義する手間が省けますし、ミュータブルな変数を利用する場面を減らすこともできます。

5. まとめ

今回は、Rustの変数、定数、シャドーイングについて学ぶことができました。

デフォルトがイミュータブルなので、処理の途中で不必要な値の変更などが起こらなくなりますし、チェックする手間が省けたりするのでプログラマとして嬉しい限りです。

投稿者プロフィール

OkawaRyouta
最新の投稿

関連記事

  1. 【Rust】列挙型

  2. 【Rust】Unsafe Rust

  3. 【Rust】所有権システム、所有権の移動

  4. 【Rust】タプル型、配列型

  5. 【Rust】構造体

  6. 【Rust】ベクタ、スライス

最近の記事

  1. AWS
  2. AWS
  3. AWS
  4. AWS
  5. AWS
  6. AWS
  7. AWS

制作実績一覧

  1. Checkeys