Errors in Swift
In Swift, it’s idiomatic to communicate errors via throwing functions and do-catch blocks. This approach makes it easy to see which functions can throw errors and to handle them using language constructs specifically designed for error handling.
import Foundation
// By convention, throwing functions are marked with `throws`
func f(arg: Int) throws -> Int {
if arg == 42 {
// We use `throw` to raise an error
throw NSError(domain: "com.example", code: 0, userInfo: [NSLocalizedDescriptionKey: "can't work with 42"])
}
// If no error is thrown, we simply return the value
return arg + 3
}
// Enum for custom errors
enum TeaError: Error {
case outOfTea
case power
}
func makeTea(arg: Int) throws {
if arg == 2 {
throw TeaError.outOfTea
} else if arg == 4 {
// In Swift, we don't have a direct equivalent to error wrapping,
// but we can create custom errors with associated values if needed
throw TeaError.power
}
}
func main() {
for i in [7, 42] {
do {
let result = try f(arg: i)
print("f worked: \(result)")
} catch {
print("f failed: \(error.localizedDescription)")
}
}
for i in 0..<5 {
do {
try makeTea(arg: i)
print("Tea is ready!")
} catch TeaError.outOfTea {
print("We should buy new tea!")
} catch TeaError.power {
print("Now it is dark.")
} catch {
print("unknown error: \(error)")
}
}
}
main()
In this Swift code:
We use
throws
to mark functions that can raise errors.Instead of returning an error as a second return value, we use Swift’s
throw
keyword to raise errors.We create a custom
TeaError
enum to represent specific error cases, which is similar to sentinel errors in Go.Swift uses
do-catch
blocks for error handling, which is similar to try-catch in other languages.We can catch specific error types or use a general catch-all clause.
Swift doesn’t have a direct equivalent to Go’s error wrapping with
%w
, but we can create custom error types with associated values if we need to include additional context.Instead of
errors.Is
, we use pattern matching in catch clauses to handle specific error types.
This Swift code maintains the same logic and structure as the original Go code, adapted to Swift’s error handling paradigm.