从没有switch/case的枚举中获取关联值

Pup*_*ppy 7 enums swift

我有一些列举不同类型的不同案例,例如

enum X {
    case AsInt(Int)
    case AsDouble(Double)
}
Run Code Online (Sandbox Code Playgroud)

我可以switch在这些方面做得很好,以获得潜在的价值.但是,该switch声明非常令人讨厌,试图让我为其他我不关心的情况执行一些代码.例如,现在我有类似的东西

func AsInt(x: X) -> Int? {
    switch x {
    case AsInt(let num):
        return num;
    default:
        return nil;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,但总是不得不引用这种方法并且必须为每个枚举的每个案例编写一个新方法,这非常繁琐.我正在寻找的是如何简单地尝试将类型的值转换X为其中一个案例,例如

var object: X = func();
let value = obj as? Int;
if value {
    // do shit
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能简单地检查案例而不必枚举我不关心的所有案例并为他们执行一些非陈述?

可以声明value为条件的一部分而不是污染范围的任何解决方案的加分点.

Cœu*_*œur 12

实际上有多种方法可以做到这一点.

让我们通过使用计算属性扩展你的枚举:

enum X {
    case asInt(Int)
    case asDouble(Double)

    var asInt: Int? {
        // ... see below
    }
}
Run Code Online (Sandbox Code Playgroud)

解决方案 if case

通过let外面:

var asInt: Int? {
    if case let .asInt(value) = self {
        return value
    }
    return nil
}
Run Code Online (Sandbox Code Playgroud)

通过let内部:

var asInt: Int? {
    if case .asInt(let value) = self {
        return value
    }
    return nil
}
Run Code Online (Sandbox Code Playgroud)

解决方案 guard case

通过let外面:

var asInt: Int? {
    guard case let .asInt(value) = self else {
        return nil
    }
    return value
}
Run Code Online (Sandbox Code Playgroud)

通过let内部:

var asInt: Int? {
    guard case .asInt(let value) = self else {
        return nil
    }
    return value
}
Run Code Online (Sandbox Code Playgroud)

最后一个是我个人最喜欢的四种解决方案的语法.


Mar*_*n R 8

从Swift 2(Xcode 7)开始,这可以if/case和模式匹配:

let x : X = ...
if case let .AsInt(num) = x {
    print(num)
}
Run Code Online (Sandbox Code Playgroud)

范围num仅限于if语句.