2

I was working with optional in switch which I noticed switch cannot accept nil as a case!

func test(value: Bool?) { switch value { case true: print("true") case false: print("false") case nil: print("nil") } } 

Error: Switch must be exhaustive

then I used default for solving the issue, but I am looking to learn why nil cannot work in first code?

3
  • This may help: Exhaustive condition of switch case in Swift Commented Jun 25, 2022 at 1:19
  • use default instead Commented Jun 25, 2022 at 1:31
  • 1
    @Unmitigated Luckily, the Swift compiler is taught how to exhaustively match against the values of Bool Commented Jun 25, 2022 at 1:32

2 Answers 2

6

I think this is just an incorrect diagnostic. You can add a default case, and this code will work, but I'm actually surprised that works.

You see, the value you're switching on is a Bool?, but 2 of the values you're comparing it against are true and false. The typical approach for this is to use pattern matching:

func test(value: Bool?) { switch value { case .some(true): print("true") case .some(false): print("false") case .none: print("nil") } } 

This works correctly, but it's a bit wordy. Luckily, Swift has a syntactic sugar for pattern matching against optionals, ? and nil:

func test(value: Bool?) { switch value { case true?: print("true") case false?: print("false") case nil: print("nil") } } 

Both of these snippets compile and work fine. It does open a new question as to why your original cases worked, if only you added the default.

I suggest you post about this on Swift forums, to get more input from the compiler nerds :)

Sign up to request clarification or add additional context in comments.

Comments

0

An Optional is an enum with two cases, one which has the value associated: either .some(value) or .none

The correct way to use a switch for pattern matching an optional is:

switch optional { case .some(let value): // do your stuff with value case .none: // do your stuff when the optional is nil } 

Alternatively you could also use map on an optional to execute a closure when its value is not nil:

optional.map { value in // do your stuff with the value } 

With this approach the body closure passed to the map function only executes when the optional is not nil at runtime, otherwise it doesn’t executes.

2 Comments

The first code seems good, but the second one with map would capture all possible cases, so how the second one would benefit me?
It might in case you dom’t want to branch your code with a guard let or if let construct to unwrap an optional value.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.