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

为什么Swift 3中的switch语句中的类型推断不起作用?,swift,Swift,更新这在Swift 3.1中已修复 在将if-else迁移到switch语句时,我注意到类型推断不起作用。当quantityTypeIdentifier已经是该类型时,为什么我需要在每个案例中指定hkquantitypeidentifier func process(samples: [HKSample]?, quantityTypeIdentifier: HKQuantityTypeIdentifier) { DispatchQueue.main.async { [weak self]

更新这在Swift 3.1中已修复


在将
if-else
迁移到
switch
语句时,我注意到类型推断不起作用。当
quantityTypeIdentifier
已经是该类型时,为什么我需要在每个
案例中指定
hkquantitypeidentifier

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)")
                }
            }
        }
    }
}
我可以调用如下函数:

process(samples: samples, quantityTypeIdentifier: .distanceWalkingRunning)

我认为你已经发现了一个bug,或者至少你有一个合理的理由来声明它。一个简短得多的例子很好地说明了这种不一致性:

let c : UIColor = .red
switch c {
case .red : print ("red") // error
default : break
}
那不会编译。你可以在第一行说
.red
,但在第三行不能。这似乎是一个明显的矛盾

话虽如此,我当然可以解释为什么这两个不同地方的规则不同。根据
~=
运算符和形成模式的规则解析
大小写
表达式。这些规则不同于Swift中的任何其他规则(因此,例如,在某些情况下,您在
案例中说
as
,但在其他任何地方都会说
as?
)。所以很明显,这些规则需要调整才能起作用。它们已经调整到允许裸枚举案例,但不允许裸枚举类结构“案例”(即,结构的静态成员是可表示的,其中这些静态成员计算为结构本身的实例)

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

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

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

HKQuantityTypeIdentifier
不是枚举类型。这是一个结构。这可能就是原因。我在Swift手册中找不到任何东西,但在我看来,如果quantityTypeIdentifier==.distanceWalkingRunning{}
起作用,那么switch语句也应该能够处理它。这就是为什么这个
struct
不是一个
enum
,与Obj-C兼容的原因吗?@jjatie我删除了我的评论,因为我的解释不准确,但我仍然认为这是一个编译器错误,你应该向苹果报告。正如你自己所说,我相信如果它与
if
一起工作,那么它也应该与
switch
@EricAya一起工作,我现在就提交一个。谢谢