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
}
Swift 4.1. Либо вам нужно указать все случаи, либо просто включить оператор внутреннего блока по умолчанию.
Частично, почему вы видите эту ошибку, потому что компилятор не может проверить, что коммутатор является исчерпывающим без запуска кода. Выражение 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
значения являются своего рода расщепляющими волосками ...
UInt8
, и он предлагает вам добавить случай по умолчанию даже со всеми 256 номерами.
– jtbandes
1 November 2014 в 07:20
default
. A switch
на Bool
не требует случая по умолчанию, если оба true
и false
охвачены.
– vacawama
7 April 2016 в 13:06
default:
, даже если этот шаблон никогда не пострадает. – Nate Cook 4 November 2014 в 03:30switch
больше не требуетdefault
дляBool
, если у вас есть случаи дляtrue
иfalse
. Я не уверен, когда это изменение произошло, но с Swift 2.2 в Xcode 7.3, это работает. – vacawama 7 April 2016 в 13:02