Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why force unwrapping is required in case of enum and switch?

Tags:

enums

ios

swift

I have notice weird swift behaviour, because in my opinion colours variable shouldn't be force unwrapped in case of switch written below, but without unwrapping compiler shows me an error message.

enum Colours: Int { case Red = 0, White, Black }  var colours: Colours! colours = .Red  switch colours! { // <-- why I have to unwrap colours? As you can see colours are declared as '!' case .Red: break default: break } 

if colours variable is not unwrapped compiler shows me that error: enter image description here

in my opinion it is swift inconsistency, does anyone have some ideas?

like image 339
Robert Avatar asked Nov 12 '15 12:11

Robert


People also ask

What is forced unwrapping in Swift?

In these cases, Swift lets you force unwrap the optional: convert it from an optional type to a non-optional type. That makes num an optional Int because you might have tried to convert a string like “Fish” rather than “5”.

Why use implicitly unwrapped optional?

Outlets are a common example when discussing implicitly unwrapped optionals. Why does Apple use implicitly unwrapped optionals to declare outlets? The reason is simple. Every stored property of a class needs to have a valid value before the initialization of the instance is complete.

What is implicit unwrapping in Swift?

Checking an optionals value is called “unwrapping”, because we're looking inside the optional box to see what it contains. Implicitly unwrapping that optional means that it's still optional and might be nil, but Swift eliminates the need for unwrapping.


1 Answers

Update: This has been fixed in Swift 5.1. From the CHANGELOG:

SR-7799:

Enum cases can now be matched against an optional enum without requiring a '?' at the end of the pattern.

This applies to your case of implicitly unwrapped optionals as well:

var colours: Colours!  switch colours { case .red:     break    // colours is .red default:     break    // colours is .white, .black or nil } 

Previous answer:

When used in a switch statement, even implicitly unwrapped optionals are not automatically unwrapped. (A reason might be that you could not match them against nil otherwise.)

So you have to unwrap (either forcibly with colours! which will crash if colours == nil, or with optional binding), or – alternatively – match against .Red? which is a shortcut for .Some(.Red):

var colours: Colours!  switch colours { case .Red?:     break    // colours is .Red default:     break    // colours is .White, .Black or nil } 

The same holds for other pattern-matching expressions, e.g.

if case .Red? = colours {     // colours is .Red  } else {     // colours is .White, .Black or nil } 

Also this has nothing to do with enumeration types, only with implicitly unwrapped optionals in a pattern:

let x : Int! = 1  switch x { case nil:     break // x is nil case 1?:     break // x is 1 default:     break // x is some other number } 
like image 75
Martin R Avatar answered Oct 07 '22 22:10

Martin R