// dictionary
return式.
return式は、関数の実行をその場で打ち切り、指定した値を呼び出し元に返す式です1。Rustの関数は本体ブロック末尾のセミコロンを付けない式が戻り値になるため、他の言語のように毎回returnを書く必要はなく、主に条件を満たしたら途中で抜ける「早期リターン」 のために使います。値を省略したreturn;はユニット型()を返します2。
// 5000円以上の購入は送料無料。条件を満たしたら早期リターンします
fn shipping_fee(total_price: u32) -> u32 {
if total_price >= 5000 {
return 0; // ここで関数を抜けるので、以降は実行されません
}
500 // 末尾の式が通常の戻り値になります
}
fn main() {
println!("8000円の買い物: 送料{}円", shipping_fee(8000));
println!("3000円の買い物: 送料{}円", shipping_fee(3000));
}Playgroundで開く末尾の式との使い分け
関数の最後で値を返すだけなら、return total;ではなく末尾の式totalで書くのがRustの慣習です(意味は同じで、returnを書いても誤りではありません)。一方、処理の途中(ネストした分岐やループの中、早期リターンの後にも処理が続く場合など)から即座に抜けたいときはreturnが適しています。単純な二択ならif式の値として書く手もありますが、「最後は末尾の式、途中はreturn」が基本の使い分けです。
補足
return式自体の型は!(never型)
return式は決して値を生成せずに制御を移す「発散する式」で、式としての型は!(never型)です1。!はどんな型にも合わせられるため、たとえばlet fee = if ok { 500 } else { return 0 };のように、片方の分岐がreturnでもif式全体の型が壊れません。
クロージャの中のreturnはクロージャだけを抜ける
クロージャやasyncブロックの本体に書いたreturnは、そのクロージャ(asyncブロック)から値を返すだけで、それを囲む関数からは抜けません3。外側の関数ごと抜けたい場合は、クロージャから返した値を関数側で判定して改めてreturnします。
Footnotes
-
rustc error codes: E0069 — “
return;is just likereturn ();” ↩
この辞書が使われているページ
backlinks 3