如何检查枚举是否不匹配模式?

11
注意我已经阅读了这篇文章,但是那篇文章使用的是switch语句,当模式匹配时应该执行某些操作(返回true)。相反,如果模式匹配,我不想做任何操作并使用if-case语句。
我有这个枚举:
enum MyEnum {
    case a
    case b(Int)
    case c
    case d
}

这是一个实例:

let myEnum: MyEnum = .a

现在如果myEnum不等于.b,我想要做一些事情。由于.b有一个关联值,我不能简单地使用if语句检查:

if myEnum != .b { // compiler error
    // do my thing here
}

所以我必须使用 if-case 语句来进行模式匹配:

if case .b(_) = myEnum {

} else {
    // do my thing here
}

但是我真的很讨厌使用空if子句。这对我来说看起来不够Swifty。我尝试天真地做到这一点:

if case .b(_) != myEnum { // compiler error!
    // do my thing here
}

除了使用空的 if 子句,还有更好的方法吗?

我仍然有应该运行的代码,无论模式是否匹配,所以 guard 语句不起作用。

5个回答

17

这只是您自己代码的极简语义更改,但请注意,您可以通过将空的if子句与case模式匹配内联来“丢弃”它:

if case .b(_) = myEnum {} else {
    // do your thing here
}

或者,省略关联值为b的case的冗余模式匹配:

if case .b = myEnum {} else {
    // do your thing here
}

这看起来有点像一个guard语句,但不会退出当前作用域。


8
您可以使用一个guard:
guard case .b = myEnum else { 
    // do your stuff here
    return 
}

缺点是你必须退出作用域...


抱歉,我意识到我没有提供足够的上下文。我的代码不能在那之后直接返回。无论模式是否匹配,都需要执行一些代码。尽管如此,你值得一个赞! - Sweeper
@Sweeper 是的,我在回答后也考虑到了这一点,所以我添加了一个注释 :) - Cristik
为什么不使用一个返回枚举状态(switch)的函数或计算属性呢? - Dasem
1
请注意,在模式匹配中不需要包含(_) - Hamish

1
什么情况:
switch myEnum {
case .b(_):
    break
default:
    // do your thing here
}

不需要在模式匹配中包含(_) - Hamish

1
你可以编写一个计算属性,并根据情况返回布尔值。
enum MyEnum {
  case a
  case b(Int)
  case c

 var isCaseB: Bool {
     switch self {
       case .b(_):
         return true
       default:
         return false
       }
    }
 }

然后在您的代码中干净地检查:
if !enumVal.isCaseB {

}

我检查了你在问题中提到的答案,但我不确定你是否意味着你根本不想使用switch语句,还是只是不想将它与其他代码混合在一起。我认为这是一种良好而干净的方法,在编写任何依赖于情况的实现之前进行检查。

1
在枚举中创建一个变量,用于计算您的值是否不是.b(_)
enum MyEnum {

    case a
    case b(Int)
    case c
    case d

    var notB: Bool {
        switch self {
        case .b(_):
            return false
        default:
            return true
        }
    }
}

MyEnum.a.notB // true
MyEnum.b(1).notB  // false
MyEnum.c // true
MyEnum.d // true

虽然还有很多代码需要进行检查,但至少在实际使用时,检查只需一行代码。


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