Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Demo None handling

One of the nice features of Rust is the way None (null, undefined, etc.) values are handled. Having variables with undefined values is a major issue in any programming language. In some languages if you declare a variable, but don't initialize it then there is garbage in the variable, in others there is a special symbol called one of these names: None/null/undefined. Compilers might be happy with this and you will only find yourself in trouble during runt-time when the code tries to access the content of this variable. If this code is in some conditional, then it might happen rarely and only at an hour extremely inconvenient for your support team.

Let's see how Rust deals with this issue?

In this example the first row is just some instruction to make the linter happy in this contrived example. You can disregard it for now.

In the main function We declare a variable called answer without assigning any value to it. Later, most likely after several lines of code, we assign a value to it and try to print it.

This code works. There is not problem with this.

#![allow(clippy::needless_late_init)]

fn main() {
    let answer;

    // ...

    // What if we try to print the answer here already? Isn't it undefined, or null?
    // println!("The answer is {answer}");

    answer = 42;
    println!("The answer is {answer}");
}

However, what would happen if we enabled the println! statement before the assignment to answer?

Use variable before initialization?

#![allow(clippy::needless_late_init)]

fn main() {
    let answer;

    // ...

    // What if we try to print the answer here already? Isn't it undefined, or null?
    println!("The answer is {answer}");

    answer = 42;
    println!("The answer is {answer}");
}

In this case when Rust compiles the code it will notice that we are trying to use a variable before we initialized it:

$ cargo build
   Compiling no-null v0.1.0 (/home/gabor/work/rust.code-maven.com/books/rust-programming/src/examples/introduction/no-null-compilation-error)
error[E0381]: used binding `answer` is possibly-uninitialized
 --> src/main.rs:9:29
  |
4 |     let answer;
  |         ------ binding declared here but left uninitialized
...
9 |     println!("The answer is {answer}");
  |                             ^^^^^^^^ `answer` used here but it is possibly-uninitialized
  |
  = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0381`.
error: could not compile `no-null` (bin "no-null") due to 1 previous error