将"or"逻辑与多个"if case"语句一起使用



假设我有一个具有关联值的枚举事例,以及该枚举类型的两个变量:

enum MyEnum {
case foo, bar(_ prop: Int)
}
let var1 = MyEnum.foo
let var2 = MyEnum.bar(1)

如果我想检查两个变量是否与关联值的一般情况匹配,我可以使用逗号:

if case .bar = var1, case .bar = var2 {
print("both are bar")
}

但我需要检查中的任何一个是否与此情况匹配,如下所示:

if case .bar = var1 || case .bar = var2 {
print("at least one is bar")
}

然而,这并不能编译。有没有其他方法可以写这篇文章来使逻辑发挥作用?

我会在枚举本身上使用某种isBar属性,以便"a或b"测试保持可读性:

enum MyEnum {
case foo, bar(_ prop: Int)
var isBar: Bool {
switch self {
case .bar: return true
default: return false
}
}
}
let var1 = MyEnum.foo
let var2 = MyEnum.bar(1)
let eitherIsBar = var1.isBar || var2.isBar

我的解决方案是:

if [var1, var2].contains(.bar) {

很多时候,我希望它是另一种方式,一个单一的var可能会根据几个值进行过滤:

if [.bar, .baz].contains(var)

但事实上,如果涉及到相关的值,你必须使它们相等,并定义一个运算符。

您必须为您的枚举实现Equatable协议:

extension MyEnum: Equatable {}
func ==(lhs: MyEnum, rhs: MyEnum) -> Bool {
switch (lhs, rhs) {
case (let .bar(prop1), let .bar(prop2)):
return prop1 == prop2
case (.foo, .foo):
return true
default:
return false
}
}

然后以下代码应该可以工作:

if var1 == .bar(1) || var2 == .bar(1) {
print("at least one is bar")
}

UPD:如果你不需要检查相关值,你可以这样做模式匹配:

switch (var1, var2) {
case (.bar, _), (_, .bar): print("at least one is bar")
default: break
}

我的猜测是if caseguard case是语法糖,只是编译器支持的一个小功能,可以提高开发人员的体验。在第一种情况下,您使用的是连续条件,这也是替换&&运算符的一个语言特性,以使代码更具可读性。当您使用&&||运算符时,编译器会期望得到两个返回布尔值的表达式。case .bar = var1本身并不是一个可以单独存在的表达式,在Swift中没有上下文,因此它不被视为返回bool的表达式。

总结:

  • if caseguard case只是语法糖,与if <expression>, <expression>语法协同工作

  • CCD_ 11和CCD_。

要解决您的问题,请使用好的旧switch语句。希望能有所帮助。

最新更新