开关盒中的Swift静态变量

时间:2017-07-18 00:05:31

标签: swift switch-statement static-variables

switch-case用于比较static var s是否按预期工作。但是,指定类型或比较直接起作用。请参阅以下内容:

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条件中的相等。

1 个答案:

答案 0 :(得分:3)

在Swift中,switch-case可能会使用多个不同的规则来匹配switch - 值和case标签:

  • enum案例匹配

    在这种情况下,您可以使用带点的案例标签,但不幸的是,Animal不是enum

    (这与下面的相等不同,因为enum个案可能有关联的值。)

  • 模式匹配运算符~=

    Swift在重载中搜索switch的类型 - 值和case - 标签的类型(如果找到),应用运算符并使用Bool结果作为指示< EM>匹配。 为此,Swift需要推断case - 标签的类型,而不依赖于switch - 值,因此Swift无法使用带点符号来推断case - 标签的类型。 / p>

  • 平等==

    switch - 值为Equatable时,Swift使用等于运算符==switch - 值与case - 标签进行匹配。< / p>

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

详细行为没有明确定义,但编译器很难解决两个规则 - 模式匹配相等。 (您可能希望为~=类型定义与Equatable的自定义匹配。)

因此,在Swift 3中case中的点引线表示法 - 仅适用于enum种类型。

但是,据我检查,Swift 4已经成功了。试试Xcode 9(目前最新的是测试版3),你的代码就可以编译了。此行为可能会在Xcode 9的发行版中发生变化,但您知道如何解决此问题。