Рассмотрим следующий код Rust:
fn f() -> i32 {
loop {
println!("Infinite loop!");
}
println!("Unreachable");
}
Компилируется (с предупреждением) и запускается, несмотря на тот факт, что возвращаемый тип неверен. Казалось бы, компилятор в порядке с типом возврата ()
в последней строке, потому что он обнаруживает, что этот код недоступен.
Однако, если мы удалим последнюю точку с запятой:
fn f() -> i32 {
loop {
println!("Infinite loop!");
}
println!("Unreachable")
}
Тогда код больше не компилируется, выдавая ошибку типа:
error[E0308]: mismatched types
--> src/main.rs:14:5
|
14 | println!("Unreachable")
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `()`
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
Почему это так? Разве тип возврата не одинаков, ()
, в обоих этих фрагментах кода?
Примечание: Мне интересно понять, почему компилятор Rust ведет себя по-разному на эти два примера, т.е. как реализован компилятор Rust. Я не хотел задавать философский вопрос о том, как он «должен» себя вести с точки зрения языкового дизайна (я понимаю, что такой вопрос, вероятно, был бы вне темы 1020 *).