在 swift 5 枚举中使用 @unknown 默认值:如何抑制 "Default will never be executed" 警告?

Using @unknown default in swift 5 enum : How to suppress "Default will never be executed" warning?

假设我有一个现有代码如下:

enum SomeEnumCases {
  case existing
  case alreadyExisting
}

func doSomething(withEnums enumCase: SomeEnumCases) {
  switch enumCase {
  case .existing:
    print("This case was already existing")
  case .alreadyExisting:
    print("This case was already existing too...")
  }
}

现在,如果我要在枚举中添加一个新的 case,上面的函数将显示一个编译错误,指出 switch case 必须是详尽无遗的,我将被迫处理新丢失的 case。我会在 switch 语句中添加第三种情况,或者添加 default 语句。

现在,我为了处理这种不可预见的枚举情况,我想在上面的现有功能中添加一个 @unknown default 情况。唯一的问题是,现在它会给我一个警告说 Default will never be executed

所以问题是,我如何让我的枚举面向未来:

  1. 详尽处理所有当前枚举案例,并且
  2. 对未来的未知情况有一个默认的处理机制,并且
  3. 只有在添加新案例时才会看到警告,并且这些案例必须由默认案例处理。

这意味着,以下代码不应发出警告:

enum SomeEnumCases {
  case existing
  case alreadyExisting
}

func doSomething(withEnums enumCase: SomeEnumCases) {
  switch enumCase {
  case .existing:
    print("This case was already existing")
  case .alreadyExisting:
    print("This case was already existing too...")
  @unknown default: // <-- warning: Default will never be executed: should be suppressed
    print("Alright, this is something new and exciting !!")
  }
}

但以下代码应该发出警告:

enum SomeEnumCases {
  case existing
  case alreadyExisting
  case new
}

func doSomething(withEnums enumCase: SomeEnumCases) {
  switch enumCase { // <-- warning: Switch must be exhaustive: This should stay.
  case .existing:
    print("This case was already existing")
  case .alreadyExisting:
    print("This case was already existing too...")
  @unknown default:
    print("Alright, this is something new and exciting !!")
  }
}

是否可以通过@unknown 或其他方式实现?

警告可能有点误导,正如 spec 所说( 强调 ):

A nonfrozen enumeration is a special kind of enumeration that may gain new enumeration cases in the future—even after you compile and ship an app. Switching over a nonfrozen enumeration requires extra consideration. When a library’s authors mark an enumeration as nonfrozen, they reserve the right to add new enumeration cases, and any code that interacts with that enumeration must be able to handle those future cases without being recompiled. Only the standard library, Swift overlays for Apple frameworks, and C and Objective-C code can declare nonfrozen enumerations. Enumerations you declare in Swift can’t be nonfrozen.

因此,与其说分支永远不会被执行,还不如说该功能完全不受您的 SomeEnumCases 用户定义 Swift 枚举的支持。

在 Swift 5 中似乎没有受支持的方法来做你想做的事情,一些迹象表明添加大小写被视为一个破坏性的变化,因为它 could/would 破坏了二进制兼容性,但是 Swift 是一个不断移动的目标...