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:
in my opinion it is swift inconsistency, does anyone have some ideas?
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”.
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.
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.
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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With