UPDATE This is fixed in Swift 3.1
In migrating an if-else
to a switch
statement, I noticed that type inference wasn't working. Why do I need to specify HKQuantityTypeIdentifier
in each case
when quantityTypeIdentifier
is already of that type?
func process(samples: [HKSample]?, quantityTypeIdentifier: HKQuantityTypeIdentifier) {
DispatchQueue.main.async { [weak self] in
if let quantitySamples = samples as? [HKQuantitySample] {
for sample in quantitySamples {
switch quantityTypeIdentifier {
case HKQuantityTypeIdentifier.distanceWalkingRunning:
// code
case HKQuantityTypeIdentifier.activeEnergyBurned:
// code
case HKQuantityTypeIdentifier.heartRate:
// code
default:
fatalError("Quantity Type Identifier not implemented \(quantityTypeIdentifier)")
}
}
}
}
}
I am able to call the function like:
process(samples: samples, quantityTypeIdentifier: .distanceWalkingRunning)
I think you've found a bug, or at least you have a reasonable case to claim one. The inconsistency is nicely shown by a much shorter example:
let c : UIColor = .red
switch c {
case .red : print ("red") // error
default : break
}
That won't compile. You can say .red
on the first line but not on the third line. That seems a clear inconsistency.
Now, having said that, I can certainly explain why the rules are different in the two different places. A case
expression is resolved according to the ~=
operator and the rules of forming a pattern. Those rules are different from anything else in Swift (hence, for example, there are situations where you say as
in a case
pattern but would say as?
everywhere else). So evidently those are the rules that would need tweaking in order for this to work. They have been tweaked so far as to allow bare enum cases but not bare enum-like struct "cases" (that is, static members of structs that are RawRepresentable where those static members evaluate to an instance of the struct itself).
Finally, here's a skanky workaround that I like to use when case
patterns become too onerous:
let c : UIColor = .red
switch true {
case c == .red : print ("red") // heh heh
default : break
}
By switching on true
and writing out the entire boolean condition we break the bounds of pattern-matching and reenter the world of normal expressions.
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