enum WeatherType {
case cloudy(coverage: Int)
case sunny
case windy
}
I just saw this in a Swift tutorial and I can't believe they allow you to do that. Now, whenever I switch on that enum, I gotta create a special case for cloudy
!
enum WeatherType {
case cloudy(coverage: Int)
case sunny
case windy
}
I just saw this in a Swift tutorial and I can't believe they allow you to do that. Now, whenever I switch on that enum, I gotta create a special case for cloudy
!
You don't "gotta" do anything. If you don't care what the coverage is, don't ask what the coverage is. If you don't care if it's cloudy, don't ask if it's cloudy. There is nothing special about the way you write a switch for a case that has an associated value.
Suppose we have this:
let weather = WeatherType.cloudy(coverage:1)
Then this is perfectly legal:
switch weather {
case .sunny:
print("it is sunny")
default:
print("I guess it's cloudy, or maybe windy")
}
And so is this!
switch weather {
case .cloudy:
print("it is cloudy")
default:
print("I guess it's sunny, or maybe windy")
}
Nor does any law require you to write a switch statement at all. If you simply want to know whether weather
is .cloudy
, just ask:
if case .cloudy = weather {
print("yes it is cloudy")
} else {
print("I guess it's sunny, or maybe windy")
}
And if you do happen to want to know what the coverage
is, you still don't have to write a switch statement:
if case let .cloudy(cov) = weather {
print("yes it is cloudy, in fact it is \(cov)")
} else {
print("I guess it's sunny, or maybe windy")
}
What you cannot do is apply ==
. This won't compile:
if weather == .sunny { // error
To that extent, yes, an enum with an associated value behaves differently from an enum without an associated value (if that's what you're asking).
Now, whenever I switch on that
enum
, I gotta create a special case forcloudy
!
That's not true, for several reasons:
cloudy
, bunching it with default
, andcoverage
property of cloudy
, while treating cloudy
itself as a single case.coverage
you have an option to ignore it, or to act on it.Here are some examples:
switch weatherType {
case .Cloudy(_):
print("It is cloudy. I ignore the coverage.")
...
}
switch weatherType {
case .Cloudy(let coverage):
print("It is cloudy. Coverage is \(coverage).")
...
}
switch weatherType {
case .Cloudy(let coverage) where coverage > 80:
print("It is very cloudy.")
case .Cloudy(let coverage) where coverage < 20:
print("It is slightly cloudy.")
case .Cloudy(_):
print("It is cloudy.")
...
}
The Liskov Substitution Principle has to do with subclassing. Enums do not allow subclassing, so it isn't applicable here.
I'm not sure what your objection is about creating a special case for cloudy
; you have to do that anyway in a switch
if you want to specifically handle that case. The extra syntax to grab the associated value is fairly straightforward.
let weather = WeatherType.cloudy(coverage: 17)
switch weather {
case .sunny:
print("sunny")
case .windy:
print("windy")
case .cloudy(let coverage):
print("cloudy with coverage \(coverage)")
}