2017-07-18 94 views
0

switch-case用于比较static var s未按预期工作。但是,指定类型或直接比较的作品。请看下面:Swift static var in switch case

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 
    } 
} 

我相信一些关于上面是不太正确的,因为它的我得到以下编译错误:

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

请让我知道如何检查在switch-case中的相同性与if条件中的相同。

+2

用确切的错误信息更新您的问题并指出导致错误的行。 – rmaddy

回答

3

在斯威夫特,switch-case可以使用几种不同的规则相匹配的switch - 值和case标签:

  • enum情况下匹配

    在这种情况下,你可以使用点引线的情况下标签,但不幸的是,您的Animal不是enum

    (这是不一样的平等下面,如enum箱子可以具有相关联的值。)

  • 图案匹配操作者~=

    夫特搜索过载的switch - 值的类型并且case -label的类型(如果找到)适用运营商并使用Bool结果作为指示匹配。 为此,Swift需要推断case-标签的类型,而不依赖于switch-值,因此Swift无法推断带点引号的case-标签的类型。

  • 平等==

    switch - 值是Equatable,夫特使用相等操作==switch - 值匹配到case -labels。

(可能还有更多,我现在不能想到的。)

行为细节并不明确,但很难对编译器来解决两个规则 - 模式匹配平等。 (您可能需要定义与~=Equatable类型的自定义匹配。)

所以,斯威夫特3,在case -labels点引线符号只适用于enum类型。

但是,据我检查,斯威夫特4已经做到了。试试Xcode 9(目前最新版本是beta 3),并且你的代码会被编译。此行为可能在Xcode 9的发行版中发生变化,但您知道如何解决。