The Try Keyword and its Variations in Swift

The try keyword and its variations of try! and try? are used before function calls which have the possibility of throwing an error. The kind of function that can do this is known as a “throwing function”. It contains throws after the function name, but before the return type. We’ll explore the try keywords below and look at their differences.

try

The try keyword by itself (without an ! or ?) must be used within a do-catch block. This makes it so we have to explicitly catch any error that’s thrown.

func loadNumbersFromDataStorage() throws -> [Int] {
    // Throw an error when there's an error
}

do {
    try loadNumbersFromDataStorage()
    
} catch {
    // Handle the error
}

try?

We aren’t required to put the try? keyword within a do-catch block, and we can simply assign the result of the function to a constant or variable. If the function throws an error at runtime, the resulting value will be nil.

let numbers = try? loadNumbersFromDataStorage()

If we want to unwrap and work with the numbers:

func processNumbers() {
    if let numbers = try? loadNumbersFromDataStorage() {
        // Run computation on the numbers
    }
}

try!

With the try! keyword, there will be a crash if the function returns nil at runtime. You should only use try! if you are completely certain that the function won’t ever throw an error when it’s called. A benefit of using this keyword (rather than try?) is the resulting value won’t be optional. This means nothing to deal with afterward to unwrap the value.

let numbers = try! loadNumbersFromDataStorage()

if numbers.contains(5) {
    print("5 exists!")
}