Swift 检查是否可以从开关中的参数创建枚举
我有一个类似于Swift 检查是否可以从开关中的参数创建枚举,swift,enums,switch-statement,Swift,Enums,Switch Statement,我有一个类似于 enum MyEnum { case a(Foo) case b case c(Bar) enum Foo: String { case one case two } enum Bar: String { case three case four } } 我正在尝试为此创建一个可失败的初始化器函数,以便您可以像 MyEnum(base: "a", para
enum MyEnum {
case a(Foo)
case b
case c(Bar)
enum Foo: String {
case one
case two
}
enum Bar: String {
case three
case four
}
}
我正在尝试为此创建一个可失败的初始化器函数,以便您可以像
MyEnum(base: "a", parameter: "one")
或
我让它像这样工作(但很笨重)
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
}
}
这将打开base
,然后在输入案例之前检查是否可以创建下一个值
但是,我现在必须创建两次Foo
或Bar
,然后强制展开第二个
有没有办法让开关盒创建
Foo
或Bar
,并且只在可以创建的情况下输入开关盒,这样我就可以使用创建的开关盒,而不必创建第二个开关盒?不要太复杂。打开base
值,并在需要时使用if
或guard
和可选绑定处理参数
:
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
}
}
易于理解,无需强制展开,Foo
或Bar
值仅创建一次(如果需要)
它还最小化了测试:例如,
MyEnum(base:“a”,参数:nil)
将转到“a”
案例并返回nil
。在switch语句中,它将无法匹配(“a”,让p?
大小写,然后仍然检查其余的大小写。另一种选择是切换两个Foo
和Bar
初始值设定项:
init?(base: String, parameter: String?) {
switch (base, parameter.flatMap { Foo.init(rawValue: $0) ?? Bar(rawValue: $0) } as Any?) {
case ("a", let foo as Foo):
self = .a(foo)
case ("b", _):
self = .b
case ("c", let bar as Bar):
self = .c(bar)
default:
return nil
}
}
缺点是,如果Foo
和Bar
有共同的情况,那么您可能无法得到想要的结果。另外,如果案例数量增加,那么开关上的表达式也可能会增加
你在开关中有两次“a”
,是打字错误吗?@RobertDresler,~~这些案例有不同的,其中谓词,它们不一样。~~哦,等等,第二个应该是“c”。不要把它弄得太复杂。打开base
,如果让p=parameter,让foo=foo(rawValue:p)
(或guard-let…
)。或者跳过Switch
语句,只使用if
语句:如果base==a,让p=parameter,让foo=foo(rawValue:p)
,在tempp
变量中没有必要,只要让foo/bar=parameter.flatMap(foo/bar.init)
就可以了。@user28434:这是另一种选择,但我觉得这更容易阅读(当然是基于观点的)。
init?(base: String, parameter: String?) {
switch (base, parameter.flatMap { Foo.init(rawValue: $0) ?? Bar(rawValue: $0) } as Any?) {
case ("a", let foo as Foo):
self = .a(foo)
case ("b", _):
self = .b
case ("c", let bar as Bar):
self = .c(bar)
default:
return nil
}
}