Here's a simple program:
fn main() { let x = { 2 + 2 }; let y = { 2 + 2; }; println!("Hello, world! {:?} {:?}", x, y); } % cargo build % ./target/debug/hello_world Hello, world! 4 ()Now, what happened here? Semicolon is a statement separator, so "2+2;" means "two plus two, and null statement". The last statement in a block is the return value, so y gets the null type (called the unit type in Rust, it always has the null value - "()").
Not the friendliest behavior.
A slight change in style helps here:
fn main() { let x = { 2 + 2 }; let y: i32 = { 2 + 2; }; println!("Hello, world! {:?} {:?}", x, y); }Now we get a compiler error, and a nice one:
% cargo build Compiling hello_world v0.1.0 (file:///usr/local/ned/dev/gitned/rust/hello_world) error[E0308]: mismatched types --> src/main.rs:3:16 | 3 | let y: i32 = { 2 + 2; }; | ^^^^^^^-^^ | | | | | help: consider removing this semicolon | expected i32, found () | = note: expected type `i32` found type `()` error: aborting due to previous error error: Could not compile `hello_world`. To learn more, run the command again with --verbose.
I guess the takeaway is to give type definitions as much as possible, particularly when dealing with blocks...