3

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.

nhgrif
  • 61,578
  • 25
  • 134
  • 173
Matthew Quiros
  • 13,385
  • 12
  • 87
  • 132

1 Answers1

10

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.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382