関数と制御フロー
関数
fn で関数を定義する.引数と戻り値には型を書く:
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let result = add(1, 2);
println!("{}", result); // 3
}
気づいただろうか — add の中に return がない.Rust では最後の式がそのまま戻り値になる.セミコロン ; を付けると「文」になって値を返さなくなるので注意:
fn add(a: i32, b: i32) -> i32 {
a + b // ← セミコロンなし = この値を返す
}
fn add_wrong(a: i32, b: i32) -> i32 {
a + b; // ← セミコロンあり = 値を返さない = コンパイルエラー
}
もちろん return を使って明示的に返すこともできる:
fn add(a: i32, b: i32) -> i32 {
return a + b;
}
途中で抜けたいときは return を使う.最後の式で返せるときはセミコロンなしで書くのが Rust 流.
戻り値がない関数
何も返さない関数は -> を省略する:
fn greet(name: String) {
println!("Hello, {}!", name);
}
if / else
fn main() {
let x = 42;
if x > 0 {
println!("positive");
} else if x < 0 {
println!("negative");
} else {
println!("zero");
}
}
条件式に () は不要.つけるとコンパイラに「いらないよ」と怒られる.
if は式
Rust の if は式なので,値を返せる:
fn main() {
let x = 42;
let label = if x > 0 { "positive" } else { "negative" };
println!("{}", label);
}
三項演算子(? :)の代わりに使える.
match
match はパターンマッチ.他言語の switch の強化版:
fn main() {
let x = 2;
match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
_ => println!("other"), // _ はそれ以外全部
}
}
_ がデフォルトケース(switch の default).
match も式なので値を返せる:
fn main() {
let x = 2;
let name = match x {
1 => "one",
2 => "two",
_ => "other",
};
println!("{}", name); // two
}
match は後の章で enum と組み合わせると真価を発揮する.
for ループ
fn main() {
// 0 から 4 まで
for i in 0..5 {
println!("{}", i);
}
// 配列(Vec)のループ
let names = vec!["Alice", "Bob", "Charlie"];
for name in names {
println!("Hello, {}!", name);
}
}
0..5 は「0 以上 5 未満」の範囲.0..=5 にすると「0 以上 5 以下」.
vec![...]は Vec(動的配列)を作るマクロ.詳しくは後の章で.
while ループ
fn main() {
let mut count = 0;
while count < 5 {
println!("{}", count);
count += 1;
}
}
loop(無限ループ)
fn main() {
let mut count = 0;
loop {
if count >= 5 {
break;
}
println!("{}", count);
count += 1;
}
}
break で抜ける.loop も式として使える:
fn main() {
let mut count = 0;
let final_count = loop {
count += 1;
if count >= 10 {
break count; // break に値を渡すとそれが loop の戻り値になる
}
};
println!("{}", final_count); // 10
}
関数と制御フローはこれで OK.次は構造体と列挙型を学んで,自分でデータ型を作れるようになろう.