The Question Mark `?` Operator in Rust

The question mark ? operator is used for early exit an function with return type that’s compatible with the value of the ? is used on. Such as Err(e) but not many people know it can be used on None as well.

The ? operator is commonly used with Result&…


This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Billy Chan

The question mark ? operator is used for early exit an function with return type that's compatible with the value of the ? is used on. Such as Err(e) but not many people know it can be used on None as well.

The ? operator is commonly used with Result<T, E> to propagate error up the call chain. We can define a unified error enum to host all errors. Remember to take advantage of Rust's conversion method From<T> to cast foreign errors into the unified error enum. That way, we take advantage of ? operator, it will perform the conversion behind the scene.

// Unified `Error` enum
#[derive(Debug)]
enum Error {
    ParseIntError(std::num::ParseIntError),
    ParseFloatError(std::num::ParseFloatError),
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::ParseIntError(e) => write!(f, "ParseIntError: {}", e.to_string()),
            Self::ParseFloatError(e) => write!(f, "ParseFloatError: {}", e.to_string()),
        }
    }
}

impl std::error::Error for Error {}

// Convert `std::num::ParseIntError` to `Error`
impl From<std::num::ParseIntError> for Error {
    fn from(err: std::num::ParseIntError) -> Self {
        Self::ParseIntError(err)
    }
}

// Convert `std::num::ParseFloatError` to `Error`
impl From<std::num::ParseFloatError> for Error {
    fn from(err: std::num::ParseFloatError) -> Self {
        Self::ParseFloatError(err)
    }
}

fn main() -> Result<(), Error> {
    // Parse an integer and unwrap it, or throw `Error::ParseIntError`
    let _: i32 = "123".parse()?;
    let _: i32 = "not_an_integer".parse()?;

    // Parse a float and unwrap it, or throw `Error::ParseFloatError`
    let _: f64 = "not_a_number".parse()?;

    Ok(())
}

The ? operator could also perform early return on Option<T> return type.

fn get_first_char_of_second_word(phrase: &str) -> Option<char> {
    // Return `None` if the phrase consist of a single word
    phrase.split(" ").skip(1).next()?.chars().next()
}

fn main() {
    assert_eq!(get_first_char_of_second_word("Hello World"), Some('W'));
    assert_eq!(get_first_char_of_second_word("Hello?"), None);
}


This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Billy Chan


Print Share Comment Cite Upload Translate Updates
APA

Billy Chan | Sciencx (2022-10-05T16:18:01+00:00) The Question Mark `?` Operator in Rust. Retrieved from https://www.scien.cx/2022/10/05/the-question-mark-operator-in-rust/

MLA
" » The Question Mark `?` Operator in Rust." Billy Chan | Sciencx - Wednesday October 5, 2022, https://www.scien.cx/2022/10/05/the-question-mark-operator-in-rust/
HARVARD
Billy Chan | Sciencx Wednesday October 5, 2022 » The Question Mark `?` Operator in Rust., viewed ,<https://www.scien.cx/2022/10/05/the-question-mark-operator-in-rust/>
VANCOUVER
Billy Chan | Sciencx - » The Question Mark `?` Operator in Rust. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/10/05/the-question-mark-operator-in-rust/
CHICAGO
" » The Question Mark `?` Operator in Rust." Billy Chan | Sciencx - Accessed . https://www.scien.cx/2022/10/05/the-question-mark-operator-in-rust/
IEEE
" » The Question Mark `?` Operator in Rust." Billy Chan | Sciencx [Online]. Available: https://www.scien.cx/2022/10/05/the-question-mark-operator-in-rust/. [Accessed: ]
rf:citation
» The Question Mark `?` Operator in Rust | Billy Chan | Sciencx | https://www.scien.cx/2022/10/05/the-question-mark-operator-in-rust/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.