Использование @unknown default в перечислении swift 5: как подавить предупреждение «По умолчанию никогда не будет выполнено»? - PullRequest
7 голосов
/ 30 марта 2019

Допустим, у меня есть существующий код следующим образом:

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 к существующей функции выше.Единственная проблема заключается в том, что теперь мне выдаст предупреждение: «1007 *.

». Итак, вопрос в том, как я могу защитить свой enum таким образом, чтобы я мог:

  1. Исчерпывающая обработка всех текущих случаев перечисления, И
  2. Иметь механизм обработки по умолчанию для будущего неизвестного случая, И
  3. Просматривать предупреждение только при добавлении новых случаев, и эти случаи должны обрабатываться по умолчаниюcase.

Это означает, что следующий код НЕ ДОЛЖЕН предупреждать:

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

Isэто возможно через @unknown или иначе?

1 Ответ

6 голосов
/ 30 марта 2019

Предупреждение, вероятно, несколько вводит в заблуждение, поскольку spec говорит ( выделение добавлено ):

A незамерзающее перечисление являетсяособый вид перечисления, который может получить новые случаи перечисления в будущем - даже после того, как вы скомпилируете и отправите приложение.Переключение на незамерзающую нумерацию требует дополнительного рассмотрения.Когда авторы библиотеки помечают перечисление как незамерзающее, они оставляют за собой право добавлять новые случаи перечисления, и любой код, взаимодействующий с этим перечислением , должен иметь возможность обрабатывать эти будущие случаи без перекомпиляции.Только стандартная библиотека, оверлеи Swift для фреймворков Apple и код C и Objective-C могут объявлять не замороженные перечисления. Перечисления, которые вы объявляете в Swift, не могут быть незамерзающими .

Так что ветвь не будет выполняться так, как надо, но функция полностью не поддерживается для вашего SomeEnumCasesопределяемое пользователем Swift enum.

В Swift 5, похоже, не существует поддерживаемого способа делать то, что вы хотите, и некоторые признаки того, что добавление наблюдений рассматривается как критическое изменение, поскольку оно может / может нарушить бинарную совместимость, ноСвифт - постоянно движущаяся цель ...

...