The Result Type

Capture an operation's outcome — a value or an error — as a single value with Result<Success, Failure> . Learn its .success / .failure cases, the get() bridge to try/catch , and when to choose it over a throwing function.

Learn The Result Type in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ Result Basics — .success and .failure

Result<Success, Failure> is an enum with two cases. Build a value with .success(...) or .failure(...) (the failure type must conform to Error ), then unwrap it with a switch .

2️⃣ Bridging to try/catch with get()

get() returns the success value or throws the contained error — so you can drop a Result straight into do/try/catch code.

3️⃣ Result vs Throwing

A throwing function surfaces the error immediately at the call site; a Result packages the outcome as a value you can store or pass to a callback that can't throw. They convert easily: Result {' try ... '} wraps a throwing call, and map transforms the success value.

Your turn. Fill in the failure and success case constructors.

📋 Quick Reference

No blanks this time — just a brief and an outline. Return a Result from a validator and handle both cases.

Practice quiz

What is Result in Swift?

  • A networking class
  • A type of optional
  • An enum with two cases representing success or failure
  • A UI view

Answer: An enum with two cases representing success or failure. Result is a generic enum with .success and .failure cases that bundles an outcome and its possible error.

What are the two cases of Result<Success, Failure>?

  • .success and .failure
  • .ok and .error
  • .value and .nil
  • .some and .none

Answer: .success and .failure. Result has exactly two cases: .success(Success) and .failure(Failure).

What constraint does the Failure type of Result have?

  • It must be a class
  • It must be an Int
  • It has no constraint
  • It must conform to the Error protocol

Answer: It must conform to the Error protocol. Result<Success, Failure> requires Failure: Error, so the failure case carries an Error value.

How do you wrap a successful Int value of 42 in a Result?

  • Result(42)
  • .success(42)
  • .value(42)
  • .ok(42)

Answer: .success(42). You construct a success with .success(42).

What does calling get() on a Result do?

  • Returns the success value or THROWS the failure's error
  • Always returns nil
  • Returns a Bool
  • Crashes on success

Answer: Returns the success value or THROWS the failure's error. get() returns the wrapped success value, or throws the contained error if it's a failure — bridging Result back to try/catch.

How do you typically handle a Result value?

  • With a for loop
  • With optional chaining
  • With a switch over .success(let value) and .failure(let error)
  • With guard only

Answer: With a switch over .success(let value) and .failure(let error). A switch with .success(let value) and .failure(let error) cases is the idiomatic way to handle a Result.

How does Result differ from a throwing function?

  • They are identical
  • Result is a value you can store and pass around; throwing happens immediately at the call site
  • Result cannot represent errors
  • Throwing functions cannot fail

Answer: Result is a value you can store and pass around; throwing happens immediately at the call site. Result captures the outcome as a value (great for callbacks/storage), while throwing surfaces the error right where it's called.

Why is Result especially handy in completion handlers / callbacks?

  • It is faster
  • It avoids optionals entirely
  • It is required by SwiftUI
  • A completion handler can't throw, so Result lets it deliver either a value or an error as one parameter

Answer: A completion handler can't throw, so Result lets it deliver either a value or an error as one parameter. Asynchronous callbacks can't use try/catch, so passing a Result cleanly carries success or failure in a single argument.

What does Result's map method do?

  • Filters the failure
  • Transforms the success value while leaving a failure untouched
  • Converts to an optional
  • Throws the error

Answer: Transforms the success value while leaving a failure untouched. map applies a transform to the success value and passes any failure through unchanged.

Given 'let r: Result<Int, Error>', how do you safely convert it to try/catch style?

  • r.value
  • r!
  • do { let v = try r.get() } catch { … }
  • r as? Int

Answer: do { let v = try r.get() } catch { … }. try r.get() inside a do/catch returns the value or throws the error, bridging Result to throwing code.