diff options
Diffstat (limited to 'src/doc/rust-by-example/src/std/result.md')
-rw-r--r-- | src/doc/rust-by-example/src/std/result.md | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/doc/rust-by-example/src/std/result.md b/src/doc/rust-by-example/src/std/result.md new file mode 100644 index 000000000..b812b9de9 --- /dev/null +++ b/src/doc/rust-by-example/src/std/result.md @@ -0,0 +1,74 @@ +# `Result` + +We've seen that the `Option` enum can be used as a return value from functions +that may fail, where `None` can be returned to indicate failure. However, +sometimes it is important to express *why* an operation failed. To do this we +have the `Result` enum. + +The `Result<T, E>` enum has two variants: + +* `Ok(value)` which indicates that the operation succeeded, and wraps the + `value` returned by the operation. (`value` has type `T`) +* `Err(why)`, which indicates that the operation failed, and wraps `why`, + which (hopefully) explains the cause of the failure. (`why` has type `E`) + +```rust,editable,ignore,mdbook-runnable +mod checked { + // Mathematical "errors" we want to catch + #[derive(Debug)] + pub enum MathError { + DivisionByZero, + NonPositiveLogarithm, + NegativeSquareRoot, + } + + pub type MathResult = Result<f64, MathError>; + + pub fn div(x: f64, y: f64) -> MathResult { + if y == 0.0 { + // This operation would `fail`, instead let's return the reason of + // the failure wrapped in `Err` + Err(MathError::DivisionByZero) + } else { + // This operation is valid, return the result wrapped in `Ok` + Ok(x / y) + } + } + + pub fn sqrt(x: f64) -> MathResult { + if x < 0.0 { + Err(MathError::NegativeSquareRoot) + } else { + Ok(x.sqrt()) + } + } + + pub fn ln(x: f64) -> MathResult { + if x <= 0.0 { + Err(MathError::NonPositiveLogarithm) + } else { + Ok(x.ln()) + } + } +} + +// `op(x, y)` === `sqrt(ln(x / y))` +fn op(x: f64, y: f64) -> f64 { + // This is a three level match pyramid! + match checked::div(x, y) { + Err(why) => panic!("{:?}", why), + Ok(ratio) => match checked::ln(ratio) { + Err(why) => panic!("{:?}", why), + Ok(ln) => match checked::sqrt(ln) { + Err(why) => panic!("{:?}", why), + Ok(sqrt) => sqrt, + }, + }, + } +} + +fn main() { + // Will this fail? + println!("{}", op(1.0, 10.0)); +} +``` |