为什么类型推断在Swift 3中的这个switch语句中不起作用?

jja*_*tie 5 swift

更新这在Swift 3.1中得到修复

在迁移if-elseswitch语句时,我注意到类型推断不起作用.为什么我需要HKQuantityTypeIdentifier在每个类型中指定case何时quantityTypeIdentifier属于该类型?

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)")
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我能够调用这样的函数:

process(samples: samples, quantityTypeIdentifier: .distanceWalkingRunning)
Run Code Online (Sandbox Code Playgroud)

mat*_*att 3

我认为你已经发现了一个错误,或者至少你有一个合理的理由来声明一个错误。一个更短的例子很好地展示了这种不一致:

let c : UIColor = .red
switch c {
case .red : print ("red") // error
default : break
}
Run Code Online (Sandbox Code Playgroud)

那不会编译。你可以.red在第一行说,但不能在第三行说。这似乎是一个明显的不一致。

现在,话虽如此,我当然可以解释为什么两个不同地方的规则不同。表达式根据运算符和形成模式的规则case来解析。这些规则与 Swift 中的其他任何规则都不同(因此,例如,在某些情况下,您在模式中说,但在其他任何地方都说)。显然,为了使其发挥作用,需要调整这些规则。对它们进行了调整,允许裸枚举情况,但不允许裸枚举类结构“情况”(即,RawRepresentable 的结构的静态成员,其中这些静态成员计算为结构本身的实例)。~=ascaseas?

case最后,当模式变得过于繁重时,我喜欢使用以下一个卑鄙的解决方法:

let c : UIColor = .red
switch true {
case c == .red : print ("red") // heh heh
default : break
}
Run Code Online (Sandbox Code Playgroud)

通过打开true并写出整个布尔条件,我们打破了模式匹配的界限,重新进入了正常表达式的世界。