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

Joh*_*ery 10 enums boolean-logic swift associated-value

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

enum MyEnum {
    case foo, bar(_ prop: Int)
}

let var1 = MyEnum.foo
let var2 = MyEnum.bar(1)
Run Code Online (Sandbox Code Playgroud)

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

if case .bar = var1, case .bar = var2 {
    print("both are bar")
}
Run Code Online (Sandbox Code Playgroud)

但是,我需要检查,如果两种情况相匹配,像这样的东西:

if case .bar = var1 || case .bar = var2 {
    print("at least one is bar")
}
Run Code Online (Sandbox Code Playgroud)

但是,这不编译.是否有另一种方法来编写这个以使逻辑工作?

Ger*_*eon 8

我会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
Run Code Online (Sandbox Code Playgroud)

  • 因为那甚至不编译 (2认同)

kov*_*pas 6

您必须为您的枚举实现 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
    }
}
Run Code Online (Sandbox Code Playgroud)

那么下面的代码应该可以工作:

if var1 == .bar(1) || var2 == .bar(1) {
    print("at least one is bar")
}
Run Code Online (Sandbox Code Playgroud)

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

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


Wit*_*ski 5

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

\n\n

总结一下:

\n\n
    \n
  • if caseguard case只是语法糖,与if <expression>, <expression>语法一起工作

  • \n
  • &&||只是逻辑运算符,基本上是一个需要两边有两个布尔参数的函数。

  • \n
\n\n

要解决您的问题,请使用旧的 switch 语句。\n希望它有帮助。

\n


Phi*_*ley 5

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

if [var1, var2].contains(.bar) {
Run Code Online (Sandbox Code Playgroud)

很多时候我希望以另一种方式,一个可能基于多个值过滤的变量:

if [.bar, .baz].contains(var)
Run Code Online (Sandbox Code Playgroud)

但确实,如果涉及相关值,您必须使它们相等并定义一个运算符。