2.12 Error Handling
Rust avoids exceptions, preferring Result<T, E>
for recoverable errors and Option<T>
for optional values. Both types are variants of Rust's powerful enum
data type.
2.12.1 Result
Type
fn divide(a: f64, b: f64) -> Result<f64, String> { if b == 0.0 { Err(String::from("Cannot divide by zero")) } else { Ok(a / b) } } fn main() { match divide(4.0, 2.0) { Ok(result) => println!("Result is {}", result), Err(e) => println!("Error: {}", e), } }
The Result
type provides the variants Ok
and Err
to indicate success or failure.
2.12.2 Option
Type
fn divide(numerator: f64, denominator: f64) -> Option<f64> { if denominator == 0.0 { None } else { Some(numerator / denominator) } } fn main() { let result = divide(10.0, 2.0); match result { Some(value) => println!("Result: {}", value), None => println!("Cannot divide by zero"), } }
Option
has the variants Some(T)
and None
to indicate the presence or absence of a value.
2.12.3 Comparison with C
C functions often signal errors by returning a special code (like -1
) and setting errno
:
#include <stdio.h>
#include <errno.h>
int divide(double a, double b, double *result) {
if (b == 0.0) {
errno = EDOM;
return -1;
} else {
*result = a / b;
return 0;
}
}
Rust's explicit types (Result
, Option
) reduce the ambiguity of error codes.