Result Examples
This page was last reviewed on Feb 24, 2023.
Dot Net Perls
Result. This is an enum type in Rust that indicates whether a function call succeeded or failed. It can return a helpful error message, along with a value.
Some important points. Results must be somehow used—they cannot just be ignored. The question mark operator will return a result from another function call.
Question mark example. This program implements simple result-handling and uses the question mark to propagate an error from another function. In main we call the test() function twice.
And Test() returns a result. The value returned is a usize, and the second argument is an error message string.
Detail Consider the test() function. The first statement is another function call to test_inner.
Important Test calls test_inner() with a question mark. If test_inner returns Err, test() propagates this result and test does not finish.
fn test_inner(argument: usize) -> Result<usize, &'static str> { if argument == 6 { Err("Not valid") } else { Ok(argument) } } fn test(argument: usize) -> Result<usize, &'static str> { // Use question mark to propagate the error from another call. test_inner(argument)?; // Valid. Ok(100) } fn main() { // Call with argument 5, this is valid. if let Ok(result) = test(5) { println!("Result: {result}"); } // Call with argument 6, this causes an error. let result = test(6).unwrap(); println!("Result: {result}"); }
Result: 100 thread main panicked at called Result::unwrap() on an Err value: "Not valid", ... note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
Flatten result iter. It is possible to use flatten() on an iterator of Results. Such iterators are returned by BufReader and its lines() functions.
Version 1 This version of the code uses open() and BufReader to get an iterator of Results, and it uses flatten on them.
Version 2 Here we do the same thing as version A, but we use map() an internal unwrap call.
Info Using flatten() with a Result iterator can be elegant and clear to read. The test1() function is shorter and simpler than test2.
use std::io::*; use std::fs::*; pub fn test1(path: &str) -> Vec<String> { if let Ok(file) = File::open(path) { let reader = BufReader::new(file); // Version A: We can use flatten on an iterator of options. reader.lines().flatten().collect() } else { vec![] } } pub fn test2(path: &str) -> Vec<String> { if let Ok(file) = File::open(path) { let reader = BufReader::new(file); // Version B: We can use map to unwrap each option. reader.lines().map(|l| l.unwrap()).collect() } else { vec![] } } fn main() { println!("{:?}", test1("/Users/sam/test.txt")); println!("{:?}", test2("/Users/sam/test.txt")); }
Hello Website Visitor
["Hello", "Website", "Visitor"] ["Hello", "Website", "Visitor"]
Is_ok, is_err. Suppose we call a function that returns a result. We need to handle this result to avoid a compile-time warning.
So We can use the is_ok and is_err functions on the Result that is returned.
Tip These functions are usually used in if-statements—here we print messages if we have an "ok" or "err" result.
use std::fs; fn main() { // Try to delete this file, and use is_ok and is_err. let path = "/does/not/exist"; if fs::remove_file(&path).is_ok() { println!("Not reached"); } if fs::remove_file(&path).is_err() { println!("IS ERR"); } }
IO Result. Usually Results are used with code that handles input and output (file handling). But the concept is the same with any code that returns Result.
A summary. Rust has powerful data types that represent Options and Results. With a Result, we can use a question mark to reuse the result from a function call and return.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Feb 24, 2023 (edit).
© 2007-2024 Sam Allen.