« All posts

01.19.2022 - Rust / The Never Type

Rust has a special type ! to imply that there is no return value. Usually called never type.

It allows us to write code like this:

let num = match input.parse::<f32>() {
    Ok(num) => num,
    Err(_) => {
        println!("ERROR: Cannot parse the given input!");
        return;
    }
};
 
println!("Parse successfully!");

We expect the num variable to have the type f32 if the input is successfully parsed into an f32. But in case of parsing error, we want to print something on the screen and gracefully exit the application (instead of crashing it).

Although all branches of a match statement should return the same data type, because the return type of return is a !, Rust can guess the type of n. The type ! can be coerced to any other type.

In the code above, when the Err case happens, the value of num will never get assigned, and the execution also stops after the let num statement, the last println! statement will never reach.

Other than return, the break, continue, exit and panic! expressions also have ! type.

One more practical example usage of ! is when you are asking a number from the user, and only continue the execution if the input is valid:

let mut buffer = String::new();
let mut done = false;
while !done {
    println!("Please enter a valid number: ");
    std::io::stdin().read_line(&mut buffer).unwrap();
    let num = match buffer.trim().parse::<i32>() {
        Ok(num) => num,
        Err(_) => continue
    };
    println!("The number is: {}", num);
    done = true;
}

References:

Read more