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.