在swift 5枚举中使用@unknown default:如何抑制";默认值将永远不会执行”;警告

在swift 5枚举中使用@unknown default:如何抑制";默认值将永远不会执行”;警告,swift,enums,warnings,swift-playground,swift5,Swift,Enums,Warnings,Swift Playground,Swift5,假设我有一个现有代码,如下所示: enum SomeEnumCases { case existing case alreadyExisting } func doSomething(withEnums enumCase: SomeEnumCases) { switch enumCase { case .existing: print("This case was already existing") case .alreadyExisting: print

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

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...")
  }
}
现在,如果我要在enum中添加一个新的案例,上面的函数将显示一个编译错误,表示switch案例必须是详尽的,我将被迫处理新的缺失案例。我会在switch语句中添加第三种情况,或者添加默认语句

现在,为了处理这种不可预见的枚举情况,我想在上面的现有函数中添加一个
@unknown default
情况。唯一的问题是,现在它会给我一个警告说,
Default将永远不会执行

所以问题是,我如何对我的枚举进行未来证明,以便我能够:

  • 彻底处理所有当前枚举案例,以及
  • 对未来未知的情况有默认的处理机制,以及
  • 仅当添加了较新的案例并且这些案例必须由默认案例处理时,才能看到警告
  • 这意味着,以下代码不应发出警告:

    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{
    案例存在
    案例已经存在
    }
    func doSomething(withEnums enumCase:SomeEnumCases){
    开关柜{
    案例.现有:
    打印(“此案例已存在”)
    案例。已经存在:
    打印(“此案例也已存在…”)
    
    @未知默认值://警告可能有点误导,正如(强调添加的内容)

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

    因此,与其说分支永远不会执行,还不如说用户定义的Swift enum完全不支持该功能


    在Swift 5中,似乎没有支持您所希望的方式,一些迹象表明,添加案例被视为破坏性的更改,因为它可能/将破坏二进制兼容性,但Swift是一个不断移动的目标…

    与常规默认值一样,@unknown default匹配任何值;它是一个“包罗万象”但是,如果枚举的所有已知元素都尚未匹配,编译器将生成一个警告。为了更好地理解,请遵循以下链接:这是一个遗憾,因为它会让大多数开发人员推迟使用这个新的案例。如果他们真的想使用它,他们将不得不在项目中处理永久性警告“默认值将永远不会被执行”。如果您的项目中有许多枚举,并且希望对代码进行未来验证,那么这将变得站不住脚,因为最终会出现许多警告,这是任何开发人员都不希望出现的project@AdamM–如果与正确类型的“枚举”一起使用“不会出现警告,如果Swift编译器在与错误类型一起使用时发出错误以避免混淆,可能会更好。传统枚举是由一组文字值定义的类型,在C族中,该类型较弱,可以通过添加更多文字来扩展。Swift使用的枚举类型本质上是“标记的不相交并集”,它们存在于许多语言中,并且可以在C族中使用
    enum
    union
    struct
    [cont..][…cont]的组合来构造(当前)Swift编译枚举的方式添加一个新实例可能会破坏现有编译代码和现有实例之间的二进制兼容性,因此在添加任何新实例时都需要重新编译代码。这并不是说Swift不能支持非冻结的Swift样式枚举,但他们(可能)权衡权衡后选择不支持(但斯威夫特是一个不断移动的目标……)
    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 !!")
      }
    }