【问题标题】:Swift 3 enum with associated value AND function comparison带有关联值和函数比较的 Swift 3 枚举
【发布时间】:2017-07-14 09:17:54
【问题描述】:

我有这个结构,它有一个枚举属性和一个函数:

struct UserInput {
  enum State {
    case unrestricted
    case restricted(because: WarningType)

    enum WarningType {
      case offline
      case forbidden
    }
  }

  var config: UserInputConfig?
  var state: State = .unrestricted

  func isConfigured() -> Bool {
    // Arbitrary checks about the config...
  }
}

有没有办法重写以下条件,以便检查 isConfigured()state 在同一个语句中?

if case .restricted = userInput.state {
  return 1
} else if userInput.isConfigured() {
  return 1
} else {
  return 0
}

似乎因为State枚举使用了关联值,你不能简单地写if userInput.state == .restricted || userInput.isConfigured(),你需要使用if case语法。一定有办法解决这个问题?

【问题讨论】:

  • 我在我的答案中添加了一个 multi-clause condition 方法,该方法更短、更易于阅读并且会短路。

标签: swift if-statement swift3 syntax enums


【解决方案1】:

你想这样做:

if case .restricted = userInput.state || userInput.isConfigured() {
    return 1
} else {
    return 0
}

但目前没有办法用模式匹配进行ORAND 有几种方法。

通过使用DeMorgan's Laws,您可以将if a || b 转换为if !(!a && !b),并且通过颠倒if 语句的thenelse 子句,您可以只需检查if !a && !b

很遗憾,您不能说 if !(case .restricted = userInput.state),但由于您的枚举只有 2 个案例,您可以将其替换为 if case .unrestricted = userInput.state

现在,您如何将它与另一个语句一起使用?您不能使用 && 的原因与您不能使用 || 的原因相同。

您可以使用匹配两个失败条件(使用 AND)的模式来检查失败案例,如果两个失败条件都不满足,则返回 1

if case (.unrestricted, false) = (userInput.state, userInput.isConfigured()) {
    return 0
} else {
    return 1
}

等效地,您可以使用 多子句条件

if case .unrestricted = userInput.state, !userInput.isConfigured() {
    return 0
} else {
    return 1
}

除了更短且 IMO 更易于阅读之外,第二种方法可以短路并在case .unrestricted = userInput.state 失败的情况下跳过调用userInput.isConfigured

【讨论】:

  • 这实际上将充当&&,而不是||
  • 没错。我基本上将 (a || b) 替换为 !(!a && !b) ,根据德摩根定律,它是等效的。
【解决方案2】:

您可以使用switch 语句和模式匹配非常干净地做到这一点:

switch userInput.state
{
   case .unrestricted:
        return userInput.isConfigured() ? 1 : 0;

   case .restricted(_):
        return 1
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多