In the previous posts about Option and Result type in Rust language, we have seen the various ways to extract values from them. In this blog post, we're going to explore the difference between expect
, unwrap
and ? operator
in Rust
Expect method
expect
method can be used in Option
or Result
to provide user-defined message when in case of panic
// Declaring variable with Ok() variant of Result type
let a: Result<i32, &str> = Ok(100);
// expect() method panics with a provided custom message
println!("Value of variable a => {}", a.expect("Variable cannot be empty"));
Unwrap method
unwrap
method can be used in Option
or Result
to return generic system-defined message when in case of panic
// Declaring variable with Ok() variant of Result type
let a: Result<i32, &str> = Ok(100);
// unwrap() method panics with a generic message
println!("Value of variable a => {}", a.unwrap());
? Operator
? operator
can be used only for Result
type. When there are too many function calls that returns Result
type, error handling will be tedious tasks if you would like to propagate errors up to the call stack. In such case, using ?
manages some of the boilerplate of propagating errors.
In this code example, let us see how to propagate errors without using ? operator
.
fn print_me(n: i32) -> Result<i32, String> {
if n < 5 {
Ok(n)
} else {
Err(format!("Given input {n} is invalid!!!"))
}
}
fn main() -> Result<(), String> {
// Declaring variable with Ok() variant of Result type
let a: Result<i32, &str> = Ok(100);
// expect() method panics with a provided custom message
println!("Value of variable a => {}", a.expect("Variable cannot be empty"));
// unwrap() method panics with a generic message
println!("Value of variable a => {}", a.unwrap());
// When there is no ? operator to propagate errors
let r = print_me(2);
if let Err(x) = r {
return Err(x)
}
let r = print_me(30);
if let Err(x) = r {
return Err(x)
}
return Ok(())
}
If you notice, for every function call print_me
, we are doing error handling and when in case of Err
variant, we're propagating errors up to the call stack.
In contrast, let us see how to propagate errors by using ? operator
.
fn print_me(n: i32) -> Result<i32, String> {
if n < 5 {
Ok(n)
} else {
Err(format!("Given input {n} is invalid!!!"))
}
}
fn main() -> Result<(), String> {
// Declaring variable with Ok() variant of Result type
let a: Result<i32, &str> = Ok(100);
// expect() method panics with a provided custom message
println!("Value of variable a => {}", a.expect("Variable cannot be empty"));
// unwrap() method panics with a generic message
println!("Value of variable a => {}", a.unwrap());
// Propagate errors using ? operator
print_me(2)?;
print_me(30)?;
return Ok(())
}
I hope you've enjoyed reading this blog post and it helps to understand the differences between expect
, unwrap
and ? operator
usages in Rust language.
You can access the code example used in this blog post from this link.
Please feel free to share your comments if any.
Happy reading!!!
Top comments (0)