WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Rust · Intermediate · question 22 of 100

How does the ? operator work, and when should you use it?

📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

In Rust, the ‘?‘ is a syntactic sugar for error handling. It allows you to write code in a more concise and readable way, especially when working with nested functions which return a ‘Result‘ or ‘Option‘.

When you use the ‘?‘ operator, Rust will do three things:

1. Evaluate the expression on the right-hand side of the ‘?‘. 2. If the expression returns an ‘Err‘, it will return that error immediately from the enclosing function. This is similar to using ‘return‘ to return an error. 3. Otherwise, if the expression evaluates to an ‘Ok‘ value, it will unwrap that value and continue with the next line of code.

Here is an example that demonstrates the use of the ‘?‘ operator to handle errors:

    use std::fs::File;
    use std::io::Read;
    
    fn read_file(filename: &str) -> Result<String, std::io::Error> {
        let mut file = File::open(filename)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        Ok(contents)
    }

In the above code, we define a function ‘read_file‘ that takes a filename and returns a ‘Result‘ that contains either a ‘String‘ with the contents of the file or an error of type ‘std::io::Error‘. The ‘?‘ operator is used to handle errors that may occur while opening the file or reading its contents.

The ‘?‘ operator can also be used in combination with ‘match‘ expressions. Here is another example:

    fn divide(a: i32, b: i32) -> Result<i32, String> {
        if b == 0 {
            return Err(String::from("Cannot divide by zero"))
        }
        Ok(a / b)
    }
    
    fn calculate(a: i32, b: i32, c: i32) -> Result<i32, String> {
        let x = divide(a, b)?;
        let y = divide(x, c)?;
        Ok(y)
    }
    
    fn main() {
        let result = calculate(10, 2, 0);
        match result {
            Ok(value) => println!("Result: {}", value),
            Err(error) => println!("Error: {}", error),
        }
    }

In this example, we define two functions: ‘divide‘ and ‘calculate‘. The ‘calculate‘ function calls ‘divide‘ twice and combines the results. The ‘?‘ operator is used to handle errors that may occur while calling ‘divide‘.

Overall, the ‘?‘ operator is a powerful tool for handling errors in Rust, and it can help you write more readable and concise code. It should be used when you want to propagate an error up the call stack without manually unwrapping it at each level.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Rust interview — then scores it.
📞 Practice Rust — free 15 min
📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

All 100 Rust questions · All topics