Я знаком с switch
утверждениями в Swift, но мне интересно, как заменить этот кусок кода на switch
:
if someVar < 0 {
// do something
} else if someVar == 0 {
// do something else
} else if someVar > 0 {
// etc
}
swift
switch-statement
Pieter
источник
источник
Ответы:
Вот один из подходов. Предполагая,
someVar
являетсяInt
или другойComparable
, вы можете опционально назначить операнд для новой переменной. Это позволяет вам охватить его так, как вы хотите, используяwhere
ключевое слово:Это можно немного упростить:
Вы также можете
where
полностью избежать ключевого слова с помощью соответствия диапазона:источник
default: fatalError()
рано обнаруживать возможные логические ошибки.assertionFailure
кажется более безопасным вариантом, особенно при работе в команде.В Swift 5 вы можете выбрать один из следующих переключателей, чтобы заменить свой оператор if.
# 1 Использование переключателя с
PartialRangeFrom
иPartialRangeUpTo
# 2 Использование переключателя с
ClosedRange
иRange
# 3 Использование switch с предложением where
# 4 Использование switch с предложением where и присваиванием
_
# 5 Использование коммутатора с оператором
RangeExpression
протокола~=(_:_:)
# 6 Использование коммутатора с оператором
Equatable
протокола~=(_:_:)
# 7 Используя переключатель с
PartialRangeFrom
,PartialRangeUpTo
иRangeExpression
«ыcontains(_:)
методисточник
0.1
генерирует фатальную ошибку, потому что1...
охватывает только числа от 1. Таким образом, это решение работает, только еслиvalue
есть,Int
но это опасно, потому что, если тип переменной изменяется, функциональные сбои без какой-либо ошибки компилятора.switch
Заявление, под капотом, использует~=
оператор. Итак, это:Desugars к этому:
Если вы посмотрите на ссылку на стандартную библиотеку, она может сказать вам, что
~=
делать перегружено версией: включается соответствие по диапазону и уравнивание для уравниваемых вещей. (Не включено сопоставление с перечислением, которое является языковой функцией, а не функцией из библиотеки std)Вы увидите, что он не соответствует прямому логическому значению на левой стороне. Для таких сравнений вам нужно добавить оператор where.
Если только вы
~=
сами не перегружаете оператора. (Как правило, это не рекомендуется) Одна из возможностей будет выглядеть примерно так:Так что это соответствует функции, которая возвращает логическое значение слева для параметра справа. Вот что вы можете использовать для этого:
В вашем случае вы можете получить утверждение, которое выглядит следующим образом:
Но теперь вы должны определить новые
isNegative
иisPositive
функции функции. Если вы не перегружаете еще несколько операторов ...Вы можете перегрузить обычные инфиксные операторы для каррирования префиксных или постфиксных операторов. Вот пример:
Это будет работать так:
Объедините это с более ранней функцией, и ваш оператор switch может выглядеть так:
Теперь вы, вероятно, не должны использовать такие вещи на практике: это немного хитроумно. Вы (вероятно) лучше придерживаться этого
where
заявления. Тем не менее, шаблон оператора переключенияили
Кажется достаточно распространенным, чтобы об этом стоило задуматься.
источник
Ты можешь:
источник
Так как кто - то уже писал
case let x where x < 0:
здесь , является альтернативой , гдеsomeVar
этоInt
.И вот альтернатива для где
someVar
этоDouble
:источник
Вот как это выглядит с диапазонами
источник
<0
Выражение не работает (больше?) , Так что я в конечном итоге с этим:Swift 3.0:
источник
X_MAX
был заменен.greatestFiniteMagnitude
, то естьDouble.greatestFiniteMagnitude
, иCGFloat.greatestFiniteMagnitude
т.д. Таким образом , как правило, вы можете просто сделать ,case 0..< .greatestFiniteMagnitude
так как типsomeVar
уже известенvar timeLeft = 100
switch timeLeft {case 0...<=7200: print("ok") default:print("nothing") }
Почему<=
оператор не распознается? Если я пишу это без равных, это работает. Спасибоcase 0...7200:
оператор<=
является оператором сравнения. В коммутаторе вы можете использовать только операторы дальности (см. Документы)someVar
был an,Int
и я должен был сделатьDouble(
someVar) `, чтобы это сработало ...Рад, что Swift 4 решает проблему:
В качестве обходного пути в 3 я сделал:
Работает но не идеально
источник