Considere o seguinte código de ferrugem:
fn f() -> i32 {
loop {
println!("Infinite loop!");
}
println!("Unreachable");
}
Isso compila (com um aviso) e executa, apesar do tipo de retorno estar errado. Parece que o compilador está OK com o tipo de retorno da ()
última linha, porque detecta que esse código está inacessível.
No entanto, se removermos o último ponto e vírgula:
fn f() -> i32 {
loop {
println!("Infinite loop!");
}
println!("Unreachable")
}
Em seguida, o código não é mais compilado, fornecendo um erro de tipo:
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)
Por que é isso? O tipo de retorno não é o mesmo ()
em ambos os trechos de código?
Nota: Estou interessado em entender por que o compilador Rust se comporta de maneira diferente nesses dois exemplos, ou seja, como o compilador Rust é implementado. Eu não pretendia fazer uma pergunta filosófica sobre como "deveria" se comportar, da perspectiva do design da linguagem (eu entendo que essa pergunta provavelmente seria fora de tópico).
!
o tipo de retorno por causa do loop infinito, o que faz sentido. No segundo caso, há uma expressão de retorno, então o solucionador de inferência de tipo usa isso para inferir o tipo, o que também faz sentido. Eu não acho que isso esteja especificado na referência de idioma, nem acho que isso importe de alguma forma - apenas omita a declaração inacessível e você ficará bem.