Reduce Fatal Index Out of Range Errors With An Unfailable Subscript

Daily Coding Tip 025

Here’s an idea for preventing the errors that happen when you pass an array the wrong index. You may have tried to use optional binding like if let or guard let with an this way. You’d think this would give you a closure in which the value at that index is available, or skip over the closure if there was no value at that index:

let myArray = [0, 1, 2, 3, 4]
if let myElement = myArray[5] { print(myElement) }

But you’d be wrong! The return value of using a subscript this way is not an optional, and so optional binding is impossible. Even though we aren’t sure that the index is within range, we are still guaranteeing that a result will be found.

This is why index out of range is a fatal error, as there is no possible way to return the correct type.

With dictionaries it’s different. As Hacking With Swift points out, dictionaries will return nil if you search for the value of a key that doesn’t exist.

Instead of messing with the existing subscript for arrays, making it return nil when it is out of range, I’ve made two new subscripts. One of them takes a non-optional default, and therefore guarantees that the result will never be optional unless there are optionals in the array. The other takes an optional default which could be nil, so there’s no way to be certain that the result won’t be optional.

So how do we use this?

I made a few examples that I think highlight the main use for them:

I’ve copied the syntax of how it works with dictionaries, but dictionaries can’t be given nil as a default.

That’s because they don’t need to specify that nil should be returned, as this already happens when no value was found at that index.

Get more Daily Coding Tips in your inbox!