可以从交换机中的参数创建检查枚举

Fog*_*ter 2 enums switch-statement swift

我有一个类似于...的枚举

enum MyEnum {
    case a(Foo)
    case b
    case c(Bar)

    enum Foo: String {
        case one
        case two
    }

    enum Bar: String {
        case three
        case four
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试为此创建一个可失败的初始化函数,以便您可以将其称为...

MyEnum(base: "a", parameter: "one")
Run Code Online (Sandbox Code Playgroud)

要么

MyEnum(base: "b", parameter: nil)
Run Code Online (Sandbox Code Playgroud)

我有这样的工作(但它很笨重)像这样...

init?(base: String, parameter: String?) {
    switch (base, parameter) {
    case ("a", let p?) where Foo(rawValue: p) != nil:
        self = .a(Foo(rawValue: p)!)
    case ("b", _):
        self = .b
    case ("c", let p?) where Bar(rawValue: p) != nil:
        self = .c(Bar(rawValue: p)!)
    default:
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

这将打开base,然后在输入案例之前检查是否可以创建下一个值.

但是,我现在必须创建FooBar两次强制打开第二个.

有没有办法让switch case创建Foo或者Bar只有在可以创建的情况下输入case,以便我可以使用那个创建的而不必创建第二个?

Mar*_*n R 5

不要太复杂.使用或和可选绑定打开base值,并处理parameter所需的位置:ifguard

init?(base: String, parameter: String?) {
    switch base {
    case "a":
        guard let p = parameter, let foo = Foo(rawValue: p) else { return nil }
        self = .a(foo)
    case "b":
        self = .b
    case "c":
        guard let p = parameter, let bar = Bar(rawValue: p) else { return nil }
        self = .c(bar)
    default:
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

易于理解,没有强制解包, Foo或者Bar只创建一次或值(如果需要).

它还最小化了测试:作为一个例子,MyEnum(base: "a", parameter: nil)将转到"a"案例并返回nil.在你的switch语句中,它将无法匹配("a", let p?)案例,然后仍然检查剩余的案例.