在swift 5枚举中使用@unknow默认值:如何禁止“默认永远不会被执行”警告?

问题描述 投票:7回答:1

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

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语句中添加第三种情况,或者添加一个默认语句。

现在,为了处理这些无法预料的枚举案例,我想在上面的现有函数中添加一个@unknown default案例。唯一的问题是,现在它会给我一个警告说Default will never be executed

所以问题是,我如何面向未来,以便我可以:

  1. 彻底处理所有当前枚举案例,AND
  2. 为未来的未知案例AND提供默认处理机制
  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或其他方式吗?

swift enums warnings swift-playground swift5
1个回答
6
投票

警告可能有些误导,因为spec说(重点补充):

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.