Search code examples
swiftswitch-statementoptional-binding

Does the underscore symbol ignore or check for nullity in a switch statement in Swift?


I have a switch statement in Swift like this:

switch tuple {
    case (let someObject, let current, nil):
        return true

    // Other cases...
}

The tuple is of type (SomeObject?, SomeObject, SomeObject?), and what I'm saying in English is: Match the case where the first two elements are not nil, while the third (an Optional) is nil.

Xcode 7 is telling me that since I didn't use the bindings someObject and current, I should replace it with an underscore. But if I replaced the first element in the tuple with an underscore, wouldn't it also match the cases where the first element is nil, because _ means the compiler ignores the value? I have a separate case for situations where the first element is nil.

For the record, it looks like my code still works as I expect it to, but I want to be sure and I can't find any documentation on this anywhere.


Solution

  • The underscore matches any value (nil or non-nil), but that is also the case for your pattern:

    case (let someObject, let current, nil):
    

    where the first let someObject matches any value (nil or non-nil). So this does actually not work as you intended.

    The optional type is defined as an enumeration:

    enum Optional<T> : ... {
        case None
        case Some(T)
        // ....
    }
    

    and nil is the same as Optional.None. Therefore you can use

    case (.Some, _, nil):
    // Alternatively: 
    case (.Some, _, .None):
    

    to match the case where the first element is not nil and the last element is nil. The middle element of (SomeObject?, SomeObject, SomeObject?) is not an optional so it cannot be nil.

    As of Swift 2 / Xcode 7, the x? pattern can be used as a synonym for .Some(x), in your case

    case (_?, _, nil):
    

    matches the case where the first element is not nil and the last element is nil.