The Result Type
Result is a special box that always holds one of two things: either a success with a value inside, or a failure with an error inside.
Syntax
func functionName() -> Result<SuccessType, ErrorType> {
return .success(value) // or .failure(error)
}
switch functionName() {
case .success(let value): /* use value */
case .failure(let error): /* handle error */
}
try functionName().get()
Creating and Switching on a Result
A Result<Success, Failure> value is created as either .success or .failure, and handled with a switch that binds each case's associated value.
Example: Creating and Switching on a Result
// Define an enum `MathError` listing its possible cases
enum MathError: Error {
// Case `divideByZero`
case divideByZero
}
// Define the function `divide` taking `a`, `b` and returning a `Result<Int, MathError>`
func divide(_ a: Int, by b: Int) -> Result<Int, MathError> {
// Check whether `b == 0`
if b == 0 {
// Return `.failure(.divideByZero)` from this function
return .failure(.divideByZero)
}
// Return `.success(a / b)` from this function
return .success(a / b)
}
// Declare a constant `result`, set to `divide(10, by: 2)`
let result = divide(10, by: 2)
// Switch on `result` and branch by case
switch result {
// Case: `.success(let value)`
case .success(let value):
// Print "Result: \(value)" to the console
print("Result: \(value)")
case .failure(let error):
print("Error: \(error)")
}
Login to try C/C++/Java/PHP code in the editor
Converting a Result to a Throwing Call
Result provides a .get() method that converts it back into a throwing expression, bridging the two error-handling styles.
Example: Converting a Result to a Throwing Call
// Define an enum `MathError` listing its possible cases
enum MathError: Error {
// Case `divideByZero`
case divideByZero
}
// Define the function `divide` taking `a`, `b` and returning a `Result<Int, MathError>`
func divide(_ a: Int, by b: Int) -> Result<Int, MathError> {
b == 0 ? .failure(.divideByZero) : .success(a / b)
}
do {
// Declare a constant `value`, set to `try divide(9, by: 0).get()`
let value = try divide(9, by: 0).get()
// Print `value` to the console
print(value)
} catch {
// Print "Caught via get(): \(error)" to the console
print("Caught via get(): \(error)")
}
Login to try C/C++/Java/PHP code in the editor
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the
view already swaps in the hi_ translation fields (or blanks these
out if untranslated), so this renders correctly for both languages
without a lang_code check here. #}
Common Mistakes
- Forgetting
Resultrequires two generic types -- the success type and the failure (error) type -- both specified in its declaration. - Using
switchon aResultbut forgetting each case binds its own associated value (.success(let value)/.failure(let error)). - Choosing
Resultfor a function's return type when a simplethrowsfunction would be simpler for synchronous code --Resultshines more for storing or passing outcomes around, especially in async callbacks.
Chapter Summary
Result<Success, Failure>represents either.success(value)or.failure(error).- It's especially useful for representing outcomes that need to be stored or passed around, not just handled immediately.
switchis the natural way to handle both cases of aResult.Resultrequires itsFailuretype to conform toError.
🔒
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: