多个“if case”语句中使用“或”逻辑

29
假设我有一个带有关联值的枚举案例,并且有两个该枚举类型的变量:

假设我有一个带有关联值的枚举案例,并且有两个该枚举类型的变量:

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")
}

然而,这段代码不能编译。有没有其他的写法可以使这个逻辑起作用?

4个回答

15

我会在枚举本身上采用某种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

我本来希望有一种更好的内置方法来完成这个任务,但看起来这可能是最简洁的选择。 - John Montgomery
为什么不直接使用 var isBar: Bool { return self == .bar } 呢? - Shehata Gamal
5
因为那甚至无法编译。 - Gereon

11

我对这种情况的解决方案是:

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

很多时候我希望实现相反的效果,即使用一个变量来存储多个基于不同数值的过滤结果。
if [.bar, .baz].contains(var)

但是,如果涉及相关值,则需要使它们可比较并定义运算符。


9
你需要为你的枚举实现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")
}

更新:如果您不需要检查相关值,可以像这样进行模式匹配:

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

1
如果您不关心case bar的相关值,这将无法正常工作。 - Mike Mertsock
不,它确实行不通。已经更新了答案,并提出了一个建议,以使其正常工作。虽然不如if case那么好看。 - kovpas
是的,你使用 switch 语句进行更新也是我能想到的最好的通用解决方案。 - Mike Mertsock
在很多情况下都不太合适 - undefined

5
我的猜测是if caseguard case只是语法糖,是编译器支持的一个小功能,旨在改善开发人员的体验。在第一种情况下,您正在使用连续条件,这也只是一种语言特性,用于替换&&运算符,使代码更易读。当您使用&&||运算符时,编译器会期望得到两个返回布尔值的表达式。case .bar = var1本身不是可以独立存在的表达式,在Swift中没有上下文,因此它不被视为返回布尔值的表达式。
总之:
  • if caseguard case只是简单的语法糖,与if <expression>, <expression>语法一起使用
  • &&||只是逻辑运算符,基本上是函数,期望在两侧都有两个布尔参数。
要解决您的问题,请使用老式的switch语句。 希望能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接