首页 > 解决方案 > 在 swift 5 枚举中使用 @unknown 默认值:如何抑制“默认值将永远不会被执行”警告?

问题描述

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

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...")
  }
}

现在,如果我要在枚举中添加一个新案例,上面的函数会显示一个编译错误,说明 switch 案例必须是详尽的,我将被迫处理新的缺失案例。我会在 switch 语句中添加第三种情况,或者添加默认语句。

现在,我为了处理这种不可预见的枚举案例,我想@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 或其他方式实现吗?

标签: swiftenumswarningsswift-playgroundswift5

解决方案


正如规范所说的那样,警告可能有点误导(强调补充):

非冻结枚举是一种特殊类型的枚举,即使在您编译和发布应用程序之后,它也可能在未来获得新的枚举案例。切换非冻结枚举需要额外考虑。当库的作者将枚举标记为非冻结时,他们保留添加新枚举案例的权利,并且与该枚举交互的任何代码都必须能够处理这些未来案例而无需重新编译。只有标准库、Apple 框架的 Swift 覆盖以及 C 和 Objective-C 代码可以声明非冻结枚举。你在 Swift 中声明的枚举不能是 nonfrozen

所以与其说分支永远不会被执行,不如说是你的SomeEnumCases用户定义的 Swift 枚举完全不支持该功能。

在 Swift 5 中似乎没有支持做你想做的事情的方式,并且一些迹象表明添加案例被视为一项重大更改,因为它可能/会破坏二进制兼容性,但 Swift 是一个不断变化的目标......


推荐阅读