変数

変数は主にlet 変数名 = 値;という文で定義します。

let foo = "foo";
let thirty_three = 33;
let truthy = true;

型は Rust がその場の記注などから自動で付与してくれる為省略できる場合があります。とはいえ型を付けても問題ありません。

let foo: &str = "foo";
let thirty_three: i32 = 33;
let truthy: bool = true;

記注することで型それに合わせてくれる場合があります。以下ではthirty_threeu32型になります。

let thirty_three: u32 = 33;

また例えばStringVec<u8>Box<str>を実装済みの為以下のような事もできます。

let ref_str: Vec<u8> = "foo".to_string().into();
// ref_str は `std::vec::Vec<u8>`
let ref_str: Box<str> = "foo".to_string().into();
// ref_str は `std::boxed::Box<str>`

Rust では結果の型に合わせて::intoのように処理が変わる事が良くあります。

タプルでまとめて定義

タプルは( )で囲みます。関数などから複数の値を同時に返すなどもできます。

let (nju, thirty_three): (&str, i32) = ("nju", 33);

変更可能な変数

letのあとにmutと続けると変数に再代入したり、

let mut value = "foo";
value = "baz";

assert_eq!(value, "baz");

編集できるようになります。

let mut num = 33;
num += 1;

assert_eq!(num, 34);

あとで代入する変数

宣言だけした場合、mutを付けなくてもあとで値を代入できます。

let value;

value = 33;

assert_eq!(value, 33);

使わない変数

下記の状態の時、Rust はfooに対してwarning: unused variable: fooのような警告を発行します。

let foo = "foo";
// 以後 `foo` を使っていない

使わないけど定義したい変数には_を頭に付けるか、_という名前で定義すると許されます。

let _foo = "foo";

関数の引数などにも使えます。

fn do_something(_: &str) {
  // snap
}

借用ルール

所有を借用する時には守らなければならない2つのルールがあります。

  1. 不変な借用であればいくらでも借用できる
  2. 可変な借用がある場合、それ以上借用できない

1つ目は以下のコードのように参照をいくつもの変数に持つ事ができます。

let mut num = 33;
let ref1 = &num;
let ref2 = &num;
let ref3 = &num;

println!("{}, {}, {}", ref1, ref2, ref3);
// 33, 33, 33

2つ目は以下のように&mut Tが既にあるスコープにさらに&Tがあるとエラーになります。

let mut num = 33;
let ref1 = &mut num;
let ref2 = &mut num;

println!("{}, {}", ref1, ref2);
// error[E0499]: cannot borrow `num` as mutable more than once at a time

定数

これにはletの代わりにconstを使います。プログラム全体の中で何度か使われる値をその度定義して使うのは良くないです。

const FOO: &str = "foo";

fn main() {
  println!("{}", FOO);
}