Unlike popular OOP languages, Rust is EOP, where EOP = expression oriented programing
When endding with ;
, that is an expression, thus block is an expression.
On the contrary, when endding without ;
, that is a statement.
We write a simple function to add one,
fn add_one(x: i32) {
x + 1;
}
fn main() {
println!("{:#?}", add_one(1));
}
./target/debug/mytest
()
Let us remove ;
,
fn add_one(x: i32) {
x + 1
}
fn main() {
println!("{:#?}", add_one(1));
}
./target/debug/mytest //can't do this
This can't be compiled, since function mismatches type tuple to i32
We modify the function,
fn add_one(x: i32) -> i32 {
x + 1
}
fn main() {
println!("{:#?}", add_one(1));
}
./target/debug/mytest
2
Someone says this is implicit return, yet I treat -> as return.
Besides, we can force type into i32
by adding return,
fn add_one(x: i32) -> i32 {
return x + 1; //without return, type mismatched
}
fn main() {
println!("{:#?}", add_one(1));
}
./target/debug/mytest
2
Now we make an option to choose,
fn add_one(x: i32, y: i32, s: i32) -> i32 {
if s == 1 {
x + 1
} else if s == 2 {
y + 1
} else {
0
}
}
fn main() {
println!("{:#?}", add_one(1, 2, 1));// choose x, not y
}
In terms of Bad Style, that is mostly in these condition flow, especially when it's getting large...
Another case would be trinary assignment,
fn add_one(x: i32, y: i32, s: i32) -> i32 {
if s == 1 { x + 1 } else { y + 1 }
}
fn main() {
println!("{:#?}", add_one(1, 2, 1));
}
More meaningfully in bool,
fn assign_value(s: bool) -> i32 {
if s { 5 } else { -5 }
}
fn main() {
println!("{:#?}", assign_value(false));
}
./target/debug/mytest
-5
In summary, we'd better not using return, instead we clarify the type for function
return
– Serrulate