Friday, March 16, 2018

Rust Monster

Ok, so the more I learn about C++, the more horrors I find. I figure, I should give Rust a try.

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...