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)
}