Results
Results are similar to options, but in addition to indicating that there is an error, we get a chance to say what kind of error it is. For example, we might write our safediv like this instead
#![allow(unused_variables)] fn main() { fn safediv(x: i32, y: i32) -> Result<i32, String> { if y == 0 { return Err(String::from("Division by zero!")); } Ok(x/y) } }
This returns a result which is either Ok
with our integer or Err
with our error. In this case the error is a String
, but we can choose any type. Often we create a custom error type. I guess this is kind of analogous to string exceptions versus exception objects in Perl. But again, there are no exceptions here in Rust; a result is an ordinary enum
with two different possibilities. As such, we can match on it, the same as with an option (or any other enum).
fn main() { match safediv(1, 2) { Ok(d) => println!("{}", d), Err(e) => println!("{}", e), } } fn safediv(x: i32, y: i32) -> Result<i32, String> { if y == 0 { return Err(String::from("Division by zero!")); } Ok(x/y) }
And, alternatively, we can use if let
.
fn main() { if let Ok(d) = safediv(1, 2) { println!("{}", d); } } fn safediv(x: i32, y: i32) -> Result<i32, String> { if y == 0 { return Err(String::from("Division by zero!")); } Ok(x/y) }
Similarly, we can unwrap a result
fn main() { let d = safediv(1, 2).unwrap(); println!("{}", d); } fn safediv(x: i32, y: i32) -> Result<i32, String> { if y == 0 { return Err(String::from("Division by zero!")); } Ok(x/y) }
Or call expect on a result
fn main() { let d = safediv(1, 2).expect("Cannot divide by zero"); println!("{}", d); } fn safediv(x: i32, y: i32) -> Result<i32, String> { if y == 0 { return Err(String::from("Division by zero!")); } Ok(x/y) }