日記(日記とは言っていない)

https://zenn.dev/23prime に移行しました。

<Rust 備忘録> 変数宣言

Rust の各種変数宣言方法に関するメモ.

メモリ管理については,別記事に記載します.

変数宣言の種類

static static mut const let let mut
global × ×
mutable × × ×
shadowing ×

グローバル変数

staticconst で宣言できる.

static ZERO: i32 = 0;
// const ZERO: i32 = 0; でもいい

#[test]
fn test_func() {
    assert_eq!(ZERO, 0);
}
  • static const 宣言では,大文字を使う文化(コンパイラからの警告は non_upper_case_globals で無視できる)
  • static は mutable にもできるが, unsafe 内でしか使えない.
static mut ZERO: i32 = 0;

#[test]
fn test_func3() {
    unsafe {
        ZERO += 1; // ここで変更
        assert_eq!(ZERO, 1);
    }
}

#[test]
fn test_func4() {
    unsafe {
        assert_eq!(ZERO, 1); // 変更は維持される
    }
}

ローカル変数

変数宣言

  • immutable
let a = 0;
a += 1; // <- error
  • mutable
let mut a = 0;
a += 1;
assert_eq!(a, 1);
  • 局所的に staticconst を使うこともできるが,当然グローバルなスコープにはならない.
fn test_func() {
    static A: i32 = 0;
    assert_eq!(A, 0);
}

fn test_func2() {
    assert_eq!(A, 0); // => cannot find value `A` in this scope
}

パターン

let (a, b) = (0, 1);
assert_eq!(a, 0);
assert_eq!(b, 1);

let [a, b] = [0, 1];
assert_eq!(a, 0);
assert_eq!(b, 1);

型注釈

let a: i32 = 0;
  • static const 宣言では,型注釈が必須である.

再宣言(シャドーイング

  • immutable な変数でもできる.
  • const ではできない.
  • 型が違ってもいい.
let a: i32 = 0;
let a: i64 = 1;
assert_eq!(a, 1);
  • static でもできる.
static A: i32 = 0;
{
    static A: i64 = 1;
    assert_eq!(A, 1);
}
assert_eq!(A, 0);

再代入(変更)

  • const や immutable な変数ではできない.
let mut a = 0;
a = 1;
a += 1;
assert_eq!(a, 2);

ブロックスコープ

  • 基本的に変数は {} 内で有効.
  {
    let a = 0;
    assert_eq!(a, 0);
  }
  assert_eq!(a, 0); // cannot find value `a` in this scope not found in this scope