Swift: Unwrapping Multiple Optionals

Believe it or not, but I’m still getting used to optionals in Swift. Just when I thought I was getting the hang of it, I came across a new use-case where I found it hard to figure out how to proceed. Here is a class similar to the one I was creating, with multiple optional values:

Swift Multiple Optionals

As you can see, the description that was printed out was definitely NOT what I had in mind! It’s weird that XCode does not give an error or warning to unwrap an optional – it just goes ahead and prints out the wrong thing. I’ll make sure to file a radar on this!

In retrospect, unwrapping the name and favoriteActivity optionals makes sense, so I tried this…

Swift Optionals Unwrapping Error

Again, maybe in retrospect this makes sense, but I was surprised that I couldn’t unwrap both optionals in one if statement.

After searching around for a bit, I found that a way to do this is through Swift’s pattern matching…

Minion Description

This may not be super intuitive, but it’s definitely powerful once I get used to it! For example, you can now pattern match for any use case of nil:

Swift Pattern Matching

Now, that’s beautiful! The resulting descriptions for my Minion class are now as expected:

Swift Pattern Matching Description

I haven’t explored pattern matching in Swift much before this, but I’m now suddenly very excited about it’s possibilities! What do you think?

UPDATE@tammofreese pointed out that I should be using .None in my switch statement instead of nil. Here is his amazing explanation from the comments below:

Tommo Freese Comment

The better solution with the .None in the swift statements looks like this:

Screen Shot 2014-08-02 at 3.13.24 PM

Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.

  • this is awesome! I was trying to figure this out just last night.

  • It’s breaking for me in Playground (b4) telling me I need to explicitly unwrap the optional with “!”. Instead, I put .Some(let name)… and it worked fine.

  • Tammo Freese

    At least with the current beta 4 compiler, better use .None instead of nil. This might add a few characters, but has two advantages.

    First, the code looks more symmetrical: (.None, .Some(x)) instead of (nil, .Some(x)).

    Second, you may have tried to use case (nil, nil): instead of default:, and then noticed the compiler complained that you have not exhausted all cases. If you use .None instead of nil, the beta 4 compiler gets that you have exhausted all cases, so you can use case (.None, .None): instead of default: for the last code sample. That states much more clearly which case it is.

    • Thanks! Good to know about the .None! I’ll update this blog post.

  • Sampriti Panda

    How much Rails do you do these days?

  • Tomasz Szulc

    Thank you for .Some and .None !

  • Pingback: Swift Notes with comments about Functional Programming « YVS()

  • JV

    “beautiful” would not be the word I would use to describe this mess needed to do something simple like “if name and favoriteActivity….” but thanks for making the previous nested if’s I was using a little less horrible.

  • Davide De Franceschi

    A faster way, if less customization is needed, is the nil-coalescing operator ??

  • Matt Luedke

    Very helpful. Thank you!

  • Guest

    Now, with Swift 1.2, if you just need to do that:

  • Kevin Hirsch

    Now, with Swift 1.2, if you just need to do a simple check for both optionals, instead of a switch, you can use the new if let name = name, favoriteActivity = favoriteActivity { //executed only if name and favoriteActivity were correctly unwrapped }

  • If you want to do it in a single Swift statement, you could also simply do
    if let name = name, let favoriteActivity = favoriteActivity {

    (I know this is 3 years old, but I somehow stumbled upon it today)