【问题标题】:How can I compare two enums with OR operator?如何将两个枚举与 OR 运算符进行比较?
【发布时间】:2022-11-11 04:56:23
【问题描述】:

我需要比较这两种情况是否符合要求,我需要做出决定,否则需要做其他事情。我尝试了很多方法,这就是其中之一,但每种方法都会出错。

if case .locked = itemStatus || case .hasHistoryLocked = itemStatus {
    print("YES")        
} else {
    print("NO")
}

【问题讨论】:

  • 我没有投反对票,但这不是Minimal reproducible example。一个完整的答案需要有人创建一个 enum 和一个变量。很少有人愿意编写所有这些代码来提供一个好的答案。这基本上归结为一个错字和对 swift 的很少研究。对于确实花时间的人,您已经在 cmets 中有附加条件。

标签: swift enums comparison


【解决方案1】:

switch 是匹配一系列案例的常用模式。见The Swift Programming Language: Enumerations: Matching Enumeration Values with a Switch Statement

例如。:

switch itemStatus {
case .locked, .hasHistoryLocked:
    print("YES")
default:
    print("NO")
}

如果您想在ifguard 语句中添加它,您可以将以上内容包装在计算属性中。例如。,

extension ItemStatus {
    var isLocked: Bool {
        switch self {
        case .locked, .hasHistoryLocked:
            return true

        default:
            return false
        }
    }
}

然后您可以执行以下操作:

func doSomethingIfUnlocked() {
    guard !itemStatus.isLocked else {
        return
    }

    // proceed with whatever you wanted if it was unlocked
}

或者,您可以为此类型添加Equatable 一致性。所以,想象ItemStatus 是这样定义的:

enum ItemStatus {
    case locked
    case hasHistoryLocked
    case unlocked(Int)
}

现在,如果这是您的类型,您可以添加 Equatable 一致性:

enum ItemStatus: Equatable {
    case locked
    case hasHistoryLocked
    case unlocked(Int)
}

如果它不是您的类型并且您不能简单地编辑原始声明,您可以添加Equatable 一致性:

extension ItemStatus: Equatable {
    static func == (lhs: Self, rhs: Self) -> Bool {
        switch (lhs, rhs) {
        case (.locked, .locked), (.hasHistoryLocked, .hasHistoryLocked):                     // obviously, add all cases without associated values here
            return true

        case (.unlocked(let lhsValue), .unlocked(let rhsValue)) where lhsValue == rhsValue:  // again, add similar patterns for all cases with associated values
            return true

        default:
            return false
        }
    }
}

但是,您将Equatable 一致性添加到ItemStatus,然后您可以执行以下操作:

func doSomethingIfUnlocked() {
    guard itemStatus != .locked, itemStatus != .hasHistoryLocked else {
        return
    }

    // proceed with whatever you wanted if it was unlocked
}

【讨论】:

  • 我需要在警卫声明中进行比较
  • 然后将此switch 语句包装在计算属性中,并将其放入您的guard 语句中。或添加Equatable 一致性。
  • 如果你原谅一个友好的建议,但如果你想在guard 声明中使用它,你应该在你的问题中包含它。我还建议添加ItemStatus 的声明(或它的简化版本,这说明为什么它还不是Equatable)。没有MRE,我们无法提供好的答案。
【解决方案2】:

正如您的评论,我看到您不想使用 Equatable 来检查枚举。还有另一种方法可以使用 Enum rawValue 检查它

因此,就像您从密钥中获取枚举的 rawValue 并将其与您的 itemStatus 进行比较一样

enum Test : Int {
    case locked = 0
    case hasHistoryLocked = 1
    case anything = 2
}

let itemStatus = 0

if itemStatus == Test.locked.rawValue || itemStatus == Test.hasHistoryLocked.rawValue {
    print("Yes")
} else {
    print("No")
}

【讨论】:

  • 运算符函数“==”要求“ItemStatus”符合“Equatable”。我的应用程序不允许这样做。
  • 亲爱的@Developer,所以改用rawValue 是不错的选择。我只是更新我的答案
  • 如果枚举不是Equatable,那通常是因为存在具有关联值的案例。因此,拥有rawValue 可能不是一个可行的模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
  • 2013-08-28
  • 1970-01-01
  • 2022-02-16
  • 2014-09-13
相关资源
最近更新 更多