Skip to main content
The Result<T, E> type in Rust is a generic enumeration used for returning and propagating the outcome of operations that can fail. It represents either a successful execution containing a value of type T, or a failed execution containing an error of type E.

Core Characteristics

  • Generics (T, E): T binds to the success value’s type, and E binds to the error value’s type. These types are entirely independent.
  • Prelude Inclusion: The Result enum and its variants (Ok and Err) are included in the Rust prelude. They are globally available without explicit use statements.
  • #[must_use] Attribute: The Rust compiler enforces error handling by emitting a warning if a function returns a Result and the caller ignores it.

Value Extraction via Pattern Matching

The fundamental mechanism for interacting with a Result is exhaustive pattern matching using the match control flow operator. This forces the developer to explicitly handle both the Ok and Err states.

The Try Operator (?)

The ? operator provides syntactic sugar for early error propagation. When appended to an expression evaluating to a Result, it unwraps the Ok value or immediately returns the Err from the enclosing function. Critical Constraint: The ? operator can only be used inside functions whose return type implements the std::ops::Try trait, such as Result or Option. Beginners frequently encounter compiler errors by attempting to use ? inside a standard main function that returns (). To use ? in main, the function signature must be modified to return a compatible type like Result<(), E>.
Under the hood, the ? operator desugars into a match expression that invokes the From trait, allowing for automatic type conversion of the error (E) into the enclosing function’s expected error type.

Collection via FromIterator

Result implements the FromIterator trait, enabling an Iterator over Result<T, E> values to be collected directly into a single Result<Collection<T>, E> (such as Result<Vec<T>, E>). During iteration, if an Err is encountered, the collection process short-circuits and returns that first Err. If all elements are Ok, it returns an Ok containing the populated collection.

Standard Library Combinators

The Result API provides functional-style combinators to transform, chain, or extract values without explicit match blocks.

Interoperability with Option

  • ok(self) -> Option<T>: Converts Result<T, E> into Option<T>, consuming self and discarding the error value.
  • err(self) -> Option<E>: Converts Result<T, E> into Option<E>, consuming self and discarding the success value.

State Interrogation

  • is_ok(&self) -> bool: Returns true if the result is Ok.
  • is_err(&self) -> bool: Returns true if the result is Err.

Transformation

  • map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U, E>: Applies a function to the Ok value, leaving an Err value untouched.
  • map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T, F>: Applies a function to the Err value, leaving an Ok value untouched.

Chaining (Monadic Operations)

  • and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E>: Calls op if the result is Ok, otherwise returns the Err value of self. Used for chaining multiple operations that return Result.
  • or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F>: Calls op if the result is Err, otherwise returns the Ok value of self.

Extraction (Panicking)

  • unwrap(self) -> T: Returns the contained Ok value. Panics if the value is an Err.
  • expect(self, msg: &str) -> T: Returns the contained Ok value. Panics with the provided custom message if the value is an Err.

Extraction (Safe Fallbacks)

  • unwrap_or(self, default: T) -> T: Returns the contained Ok value or a provided default T.
  • unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T: Returns the contained Ok value or computes a default T from a closure.
Tired of Poor Rust Skills? Fix That With Deep Grasping!Learn More