1

I know it is possible to test an optional vs optionals as described in this question: Swift: testing against optional value in switch case

But what I want to do is test a non-optional value with optional case values:

    switch nonOptionalView{
    case optionalView1:
        // Do something

    case optionalView2:
        // Do something else

    }

Xcode returns an error "Value of Optional xxx not unwrapped" and If I add a "?" at the end of the case statement, I get "? pattern cannot match values of type 'UIView'"

Community
  • 1
  • 1
the Reverend
  • 12,305
  • 10
  • 66
  • 121
  • Could you try a "!" instead of the "?" and tell me if its working? – Dennis Weidmann Aug 26 '15 at 19:22
  • Unfortunately no, it throws a unexpectedly found nil while unwrapping an Optional value – the Reverend Aug 26 '15 at 20:55
  • well then use "if let" to test it... This will unwrap it, only if it is kind of the class you are trying to cast it and never crash your app, even if the tested object is nil... If the unwrapped value could be nil (what your recent comment implies), you will also have to test the optional before the switch... please try my last comment you already tested, and add a if (nonOptionalView == nil) {return} before the switch... this will work also – Dennis Weidmann Aug 26 '15 at 21:01
  • These two ways will work for your problem – Dennis Weidmann Aug 26 '15 at 21:02
  • Thanks Neo, I was trying to avoid using if let statements, looks like it is not possible. – the Reverend Aug 26 '15 at 21:06
  • Sure, take a look at the second part of my comment... it should also solve your problem without if let... you only have to test the optional if it is nil, before you try to unwrap it with "!" – Dennis Weidmann Aug 26 '15 at 21:07

2 Answers2

1

Currently pattern matching optional values isn't supported in the Swift standard library. However, you could easily execute your logic using if/else if statements:

if nonOptionalView === optionalView1 {
    // Do something
} else if nonOptionalView === optionalView2 {
    // Do something else
}

If you'd really like to be able to pattern match optional values, you can use operator overloading. To overload the pattern matching operator ~=, place the following code in your project:

public func ~=<T : Equatable>(a: T?, b: T?) -> Bool {
    return a == b
}

Now you'll be able to pattern match optional values just fine:

switch nonOptionalView {
case optionalView1:
    // Do something
case optionalView2:
    // Do something else
default:
    // Handle default case
}
Bradley Hilton
  • 858
  • 1
  • 8
  • 7
0

You could take a look at this solution https://stackoverflow.com/a/26941591/2485238

I find the code is more readable than the if/else solution.

In your case it would be

switch nonOptionalView {
    case .Some(optionalView1):
    // Do something

    case .Some(optionalView2):
    // Do something else

    default: 
    // Handle default case
}
Community
  • 1
  • 1
Adrian
  • 324
  • 2
  • 10