末尾にセミコロンを付けると戻り値が () になり E0308 になる
Rustの関数は最後の行が式(セミコロン無し)であれば、その値をそのまま戻り値にします。セミコロンを付けるとその行は文(statement)になり、戻り値が空のタプル()に変わってしまいます。
エラーメッセージの読み方
error[E0308]: mismatched types
E0308- エラーコード — `rustc --explain E0308` で詳しい説明が見られます
mismatched types- 詳細メッセージ — 何が問題だったか
このエラーが出る典型パターン
パターン1
1 fn double(n: i32) -> i32 { 2 n * 2; ^ 3 } 4 5 fn main() { 6 println!("{}", double(3)); 7 }
error[E0308]: mismatched types
expected `i32`, found `()`
関数の最後の行はセミコロンを付けなければ式として評価され、その値が戻り値になります。セミコロンを付けるとその行は文になり、戻り値は()になります。
直し方: ; を (空) にします。
広告
広告スロット(未設定)
パターン2
1 fn triple(n: i32) -> i32 { 2 n * 3; ^ 3 } 4 5 fn main() { 6 println!("{}", triple(4)); 7 }
error[E0308]: mismatched types
expected `i32`, found `()`
戻り値の型をi32と宣言しているのに、末尾にセミコロンを付けると()を返すことになり型が一致しなくなります。
直し方: ; を (空) にします。
パターン3
1 fn square(n: i32) -> i32 { 2 n * n; ^ 3 } 4 5 fn main() { 6 println!("{}", square(5)); 7 }
error[E0308]: mismatched types
expected `i32`, found `()`
returnを書かない場合、関数本体の最後の式(セミコロン無し)がそのまま戻り値になります。
直し方: ; を (空) にします。
パターン4
1 fn increment(n: i32) -> i32 { 2 n + 1; ^ 3 } 4 5 fn main() { 6 println!("{}", increment(9)); 7 }
error[E0308]: mismatched types
expected `i32`, found `()`
他の言語のようにセミコロンを付けるだけの習慣で書くと、Rustでは戻り値の型が変わってしまいます。
直し方: ; を (空) にします。
パターン5
1 fn half(n: i32) -> i32 { 2 n / 2; ^ 3 } 4 5 fn main() { 6 println!("{}", half(10)); 7 }
error[E0308]: mismatched types
expected `i32`, found `()`
セミコロンの有無は単なる区切り記号ではなく、その行を式として扱うか文として扱うかを決める重要な違いです。
直し方: ; を (空) にします。
よくある誤解
「セミコロンは行の区切りとして付けても付けなくても同じはず」という思い込みは誤りです。関数の最後の行では、セミコロンの有無が戻り値の型そのものを変えてしまいます。
まとめ
末尾にセミコロンを付けると戻り値が () になり E0308 になるは初級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。