2016-11-15 41 views
5

UPDATE這是固定在斯威夫特3.1爲什麼類型推斷在Swift 3的這個switch語句中不起作用?

在遷移的if-elseswitch聲明,我注意到,類型推理是行不通的。爲什麼當quantityTypeIdentifier已經屬於那種類型時,我需要在每個case中指定HKQuantityTypeIdentifier

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) 
+1

'HKQuantityTypeIdentifier'不是一個枚舉類型。這是一個結構。這可能是原因。 – vadian

+0

我一直無法在Swift書中找到任何東西,但在我看來,如果'如果quantityTypeIdentifier == .distanceWalkingRunning {}'起作用,那麼switch語句也應該能夠處理它。 – jjatie

+0

這個'struct'是不是與Obj-C兼容的'enum'? – jjatie

回答

3

我想你已經發現了一個錯誤,或者至少你有一個合理的情況下,權利要求之一。不一致性通過一個更簡短的例子很好地顯示:

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

這將不會編譯。你可以在第一行中說.red,但不在第三行。這似乎明顯不一致。

現在,我已經說了,我當然可以解釋爲什麼規則在兩個不同的地方是不同的。 A case表達式根據~=運營商和形成模式的規則解決。這些規則與Swift中的其他規則不同(因此,例如,在某些情況下,您可以使用case模式表示as,但在其他地方會說as?)。顯然,這些規則需要調整才能實現。它們已被調整,以允許裸枚舉的情況,但不是純粹的枚舉類結構「案件」(即靜態成員結構的RawRepresentable,其中這些靜態成員評估結構本身的一個實例)。

最後,這裏有一個讓人反感的解決辦法,我喜歡當case模式變得過於繁重的使用方法:

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

通過對true交換和寫出我們打破模式匹配並重新進入的邊界整個布爾條件正常表達的世界。

相關問題