Rust 速習チュートリアル

Rust のスコープ

1. スコープ (Scope)

関数の仕組みを理解したところで、次に重要となるのが、変数が関数の内側や外側でどのように動作するかを学ぶことです。
スコープ(Scope)とは、変数の使用が許可されている範囲のことを指します。 変数は、それが作成されたブロックの中でのみ生存します。Rustにおいてブロックとは、波括弧 { } で囲まれたすべての範囲を指します。

2. 関数内の変数

関数の内部で作成された変数は、その関数の内部にのみ存在します。

サンプルコード

fn myFunction() {
  let message = "こんにちは!";
  println!("{}", message);  // ここではmessage変数にアクセス可能です
}

myFunction();

println!("{}", message); // エラー - 関数の外側からはmessage変数にアクセスできません

注記: 変数 message は関数の内部にのみ存在します。関数の外でそれを使用しようとすると、コンパイルエラーが発生します。

3. ブロック内の変数

if 文やループのように、他のコードの内部にブロックを作成することもできます。これらのブロック内で作成された変数は、その内部でのみ有効です。

サンプルコード

let score = 80;

if score > 50 {
  let result = "合格";
  println!("結果: {}", result);
}

println!("結果: {}", result); // エラー: resultはここではスコープ外(out of scope)です

4. 同一スコープ内の変数

Rustでは、let キーワードを使用して、同じスコープ内で同じ名前の新しい変数を宣言することができます。これはシャドウイング(Shadowing)と呼ばれます。

サンプルコード

let x = 5;
let x = 10;

println!("xの値: {}", x); // 10をプリントします

2番目の x が1番目の x を覆い隠します(シャドウイング)。2番目の宣言以降、値 5 にはアクセスできなくなります。
これは、変数名の再利用を禁止している他の言語とは異なる点です。Rustにおいて、これは値を安全に変換または更新するために使用される機能です。

4.1 新しいブロック内での変数名の再利用

新しいブロックの内部で変数名を再利用することも可能です。

サンプルコード

let x = 5;

{
  let x = 10;
  println!("ブロックの内側: {}", x);
}

println!("ブロックの外側: {}", x);

この場合、2つの x 変数は異なるスコープに存在します。内側の x はそのブロック内でのみ存在し、ブロックを抜けると外側の元の値が保持されたままとなります。

注記: シャドウイングは許可されていますが、同じ名前を多用しすぎるとコードの可読性が低下する可能性があります。可能な限り、明確で分かりやすい名前を使用してください。

5. スコープ管理が重要である理由

スコープを理解することは、以下のメリットに繋がります。

  • 変数がどこで使用可能かを正確に把握できる
  • 名前の競合(ネーミングコンフリクト)を防止できる
  • 関数、ループ、条件分岐(if文など)を扱う際の論理的なエラーを回避できる