Почему этот переключатель не является исчерпывающим? [Дубликат]

21
задан Girish Nair 1 November 2014 в 06:41
поделиться

3 ответа

Swift только по-настоящему проверяет, что блок switch является исчерпывающим при работе с типами enum. Даже для включения Bool в дополнение к true и false требуется блок default:

var b = true
switch b {
case true:  println("true")
case false: println("false")
}
// error: switch must be exhaustive, consider adding a default clause

. Однако с enum компилятор рад видеть только два случая:

enum MyBool {
    case True
    case False
}

var b = MyBool.True
switch b {
case .True:  println("true")
case .False: println("false")
}

Если вам нужно включить блок default для компилятора, но у него ничего не получится, ключевое слово break будет полезно:

var b = true
switch b {
case true:  println("true")
case false: println("false")
default: break
}
50
ответ дан Nate Cook 18 August 2018 в 00:56
поделиться
  • 1
    Итак, вы подразумеваете, что iOS говорит, что он исчерпывающий, но на самом деле это не так? – Girish Nair 1 November 2014 в 09:26
  • 2
    @GirishNair Я не уверен, что я следую - в основном, хотя мы можем сказать, что блок switch является исчерпывающим, компилятор не выполняет работу, чтобы определить это. Поэтому нам нужно предоставить default:, даже если этот шаблон никогда не пострадает. – Nate Cook 4 November 2014 в 03:30
  • 3
    Я просто испытал это с необязательным Bool и думал, что у меня что-то не хватает. Я подал сообщение об ошибке: 19582311 – hidden-username 23 January 2015 в 21:25
  • 4
    switch больше не требует default для Bool, если у вас есть случаи для true и false. Я не уверен, когда это изменение произошло, но с Swift 2.2 в Xcode 7.3, это работает. – vacawama 7 April 2016 в 13:02

Swift 4.1. Либо вам нужно указать все случаи, либо просто включить оператор внутреннего блока по умолчанию.

0
ответ дан Gurjinder Singh Khalsa 18 August 2018 в 00:56
поделиться

Частично, почему вы видите эту ошибку, потому что компилятор не может проверить, что коммутатор является исчерпывающим без запуска кода. Выражение 0...65535 создает структуру ClosedInterval, и когда оператор switch выполняется, он должен спросить эту структуру, если значение quantity находится в интервале. Там есть место для изменения во время выполнения, поэтому компилятор не может проверить его во время компиляции. (См. Проблема с остановкой .)

В более общем плане компилятор не может обнаружить исчерпывающий переключатель для целых значений - даже если вы добавляете конкретные случаи для каждого целочисленного значения (case 0: ... case 1: ... ... case 65535:), он не знает, что ваш коммутатор является исчерпывающим. (Теоретически это могло бы: рассмотрите подачу запроса функции об этом, если это то, что вы хотели бы видеть.)

Как бы то ни было, есть два сценария, в которых Swift может обнаружить полноту и позволить вам опустить предложение default: перечисление и привязка значений в кортежах. @ Ответ NateCook охватывает перечисления - если вы включаете значение enum и имеете case в своем switch для каждого case в перечислении, вам не нужно default. Вы также не нуждаетесь в метке default, если вы включаете кортеж и связываете все возможные комбинации значений, как показано в в книге Swift :

switch anotherPoint {
case (let x, 0):
    println("on the x-axis with an x value of \(x)")
case (0, let y):
    println("on the y-axis with a y value of \(y)")
case let (x, y):
    println("somewhere else at (\(x), \(y))")
}

Вы может обобщить это правило как «если система типа знает о возможных значениях вашего типа, она может обнаружить switch полноту», но тот факт, что существует уровень, на котором система типов не знает диапазон возможных (например, ) UInt32 значения являются своего рода расщепляющими волосками ...

6
ответ дан rickster 18 August 2018 в 00:56
поделиться
  • 1
    Nope ... попробовал его с помощью UInt8, и он предлагает вам добавить случай по умолчанию даже со всеми 256 номерами. – jtbandes 1 November 2014 в 07:20
  • 2
    Эх, это то, что я получаю для публикации с моего телефона, и уходит, что я наполовину помню. :) Отредактированный ответ с исправлениями и дополнительной информацией. – rickster 3 November 2014 в 23:57
  • 3
    «компилятор не может проверить, что коммутатор является исчерпывающим без запуска кода». - Это просто не соответствует действительности. – Karoly Horvath 30 May 2015 в 23:56
  • 4
    Третий случай теперь работает без default. A switch на Bool не требует случая по умолчанию, если оба true и false охвачены. – vacawama 7 April 2016 в 13:06
Другие вопросы по тегам:

Похожие вопросы: