変数は主に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_three
はu32
型になります。
let thirty_three: u32 = 33;
また例えばString
はVec<u8>
やBox<str>
を実装済みの為以下のような事もできます。
let ref_str: Vec = "foo".to_string().into();
// ref_str は `std::vec::Vec`
let ref_str: Box = "foo".to_string().into();
// ref_str は `std::boxed::Box`
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つ目は以下のコードのように参照をいくつもの変数に持つ事ができます。
let mut num = 33;
let ref1 = #
let ref2 = #
let ref3 = #
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);
}