Optionals Beware

Update: 10/20/2014 I was inappropriately applying ? to the key lookup, which of course, does nothing. It is simply not needed.

Optionals… that pesky little safe, but sometimes dangerous, construct in Swift. It's not new or unique, but they do work a bit different than other languages.

GIVE ME THE VALUE!!! In John Siracusa's Yosemite review, there's a section on Swift. In it, while talking about safety and optionals, there's a trap in here.

let ages = [
    "Tim":  53,  "Angela": 54,  "Craig":   44,
    "Jony": 47,  "Chris":  37,  "Michael": 34,
]

let people = sorted(ages.keys, <).filter { ages[$0]! < 50 }

swift

Do you spot it? It's the use of !.

And that's the problem with the !, in some cases, it is safe to use it… until you start to modify the code around the area, then it might start to get dicey.

There is a safe way to write the code that will never cause your program to crash, regardless of the refactoring you do:

let people = sorted(ages.keys, <).filter { ages[$0] < 50 }

Removing the ! provides all the safety we need. The comparison operators already handle optionals. In the case of <, when the left hand side is nil, the result is always true.

Whenever you see the ! in your code, BE CAREFUL!!! I'd go so far as recommending to never use it. There are safer ways, though, they are sometimes it is a bit more verbose.

So instead of writing this:

func |||<T>(opt: T?, defaultValue: T) -> T
{
    return opt != nil ? opt! : defaultValue
}

swift

Write this:

func |||<T>(opt: T?, defaultValue: T) -> T
{
    if let opt = opt { return opt } else { defaultValue }
}

Update: Yes, you could use ??, that's not the point. The point is just showing how to write the forced unwrapped version in way that doesn't require forced unwrapping.

Beware of the optional!

Optionals Beware