2017-07-18 2 views
0

switch-case pour la comparaison static var s ne fonctionne pas comme prévu. Cependant, spécifier un type ou comparer fonctionne directement. S'il vous plaît voir ci-dessous:Variation statique rapide dans le boîtier du commutateur

class AnimalHelper { 
    func loadAnimal(_ animal: Animal) { 

     // Doesn't compile 
     switch animal { 
      case .squirrel, .deer: loadGrass() 
      case .dolphin: return // not implemented 
      default: loadMeat() 
     } 

     // Direct comparison works 
     if animal == .squirrel || animal == .deer { 
      loadGrass() 
     } else if animal == .dolphin { 
      return // not implemented 
     } else { 
      loadMeat() 
     } 

     // Specifying the type explicitly also works 
     switch animal { 
      case Animal.squirrel, Animal.deer: loadGrass() 
      case Animal.dolphin: return // not implemented 
      default: loadMeat() 
     } 
    } 

    func loadGrass() {} 
    func loadMeat() {} 
} 

class Animal { 
    let id = 6 // Will be generated 
    let hasFourLegs = true 
    let numberOfEyes = 2 
    // ... // 

    static var squirrel: Animal { return .init() } 
    static var dolphin: Animal { return .init() } 
    static var puma: Animal { return .init() } 
    static var deer: Animal { return .init() } 
} 

extension Animal: Equatable { 
    public static func ==(lhs: Animal, rhs: Animal) -> Bool { 
     return lhs.id == rhs.id 
    } 
} 

Je suis sûr que quelque chose au sujet de ce qui précède n'est pas tout à fait raison parce que je me fais des erreurs de compilation suivantes:

Enum case 'squirrel' not found in type 'Animal' 
Enum case 'deer' not found in type 'Animal' 
Enum case 'dolphin' not found in type 'Animal' 

s'il vous plaît laissez-moi savoir comment est vérifié pour l'égalité dans un switch-case est différent de celui dans une condition if.

+2

Mettez à jour votre question avec le message d'erreur exact et indiquez la ligne qui a provoqué l'erreur. – rmaddy

Répondre

3

Swift, switch-case peut utiliser plusieurs règles différentes pour correspondre à la switch -valeur et les case étiquettes:

  • enum cas correspondant à

    Dans ce cas, vous pouvez utiliser des étiquettes de cas dot-plombée , mais malheureusement, votre Animal n'est pas enum.

    (Ce n'est pas la même chose que l'égalité ci-dessous, enum cas peuvent avoir des valeurs associées.)

  • opérateur de correspondance de motif ~=

    Swift recherches une surcharge pour le type de switch -value et le type de case -label, s'il est trouvé, applique l'opérateur et utilise le résultat Bool comme indiquant correspond à. Pour cette raison, Swift doit déduire les types d'étiquettes case indépendamment de la valeur switch, donc Swift ne peut pas déduire les types d'étiquettes case avec notation par points.

  • égalité ==

    Lorsque le switch -value est Equatable, Swift utilise l'opérateur d'égalité == pour faire correspondre la switch -value aux case -labels.

(Il peut y avoir plus que je ne peux pas penser maintenant.)

Le comportement détaillé est pas bien défini, mais il est difficile pour les statisticiens pour résoudre deux règles - motif correspondant et égalité. (Vous pouvez définir l'appariement personnalisé avec ~= pour Equatable types.)

Ainsi, à Swift 3, la notation dot-plombée dans les case -labels ne fonctionne que pour enum types. Mais, pour autant que j'ai vérifié, Swift 4 l'a fait. Essayez Xcode 9 (actuellement le dernier en date est beta 3), et votre code compilerait. Ce comportement peut changer dans la version de Xcode 9, mais vous savez comment contourner.