Ответы:
Вы можете использовать оператор "pattern-match" ~=
:
if 200 ... 299 ~= statusCode {
print("success")
}
Или оператор switch с шаблоном выражения (который внутренне использует оператор сопоставления с шаблоном):
switch statusCode {
case 200 ... 299:
print("success")
default:
print("failure")
}
Обратите внимание, что ..<
обозначает диапазон, в котором отсутствует верхнее значение, так что вы, вероятно, хотите
200 ... 299
или 200 ..< 300
.
Дополнительная информация: Когда приведенный выше код скомпилирован в Xcode 6.3 с включенной оптимизацией, то для теста
if 200 ... 299 ~= statusCode
фактически никакого вызова функции не генерируется, только три инструкции по сборке:
addq $-200, %rdi
cmpq $99, %rdi
ja LBB0_1
это точно такой же код сборки, который генерируется для
if statusCode >= 200 && statusCode <= 299
Вы можете проверить это с
xcrun -sdk macosx swiftc -O -emit-assembly main.swift
Начиная со Swift 2 это можно записать как
if case 200 ... 299 = statusCode {
print("success")
}
использование недавно введенного сопоставления с образцом для операторов if. См. Также Swift 2 - сопоставление с образцом в «если» .
func ~= (Range<A>, A) -> Bool
вызывается библиотечная функция . Я бы предположил, что эта функция работает с O (1).
xcrun -sdk macosx swift -emit-assembly main.swift
и проверил код сборки. Затем я использовал xcrun swift-demangle ...
для удаления названия вызываемой функции. - К сожалению, Xcode пока не может создать ассемблерный код для файлов Swift, возможно, он будет работать в более поздней версии.
Эта версия кажется более читаемой, чем сопоставление с образцом:
if (200 ... 299).contains(statusCode) {
print("Success")
}
Это старая ветка, но мне кажется, мы обдумываем это. Мне кажется, лучший ответ - просто
if statusCode >= 200 && statusCode <= 299
Нет никаких
if 200 > statusCode > 299
форма, о которой я знаю, и другие предлагаемые решения выполняют вызовы функций, которые труднее читать и могут выполнять медленнее. Метод сопоставления с образцом - полезная уловка, но он плохо подходит для этой проблемы.
Лично я считаю оператор сопоставления с образцом отвратительным и хотел бы, чтобы компилятор поддерживал if x in 1...100
синтаксис. Это оооочень более интуитивно и легко читается, чемif 1...100 ~= x
if 200 ... 299 ~= statusCode
, без вызова функции :)
if 200 ... 299 ~= statusCode
дает тот же код сборки, что иif statusCode >= 200 && statusCode <= 299
Я хотел проверить ошибки 4xx, кроме 401. Вот код:
let i = 401
if 400..<500 ~= i, i != 401 {
print("yes")
} else {
print("NO")
}
Я тоже предпочитал оператор Range .contains (), пока не обнаружил, что его реализация неэффективна - https://oleb.net/blog/2015/09/swift-ranges-and-intervals/
Мы можем представить условие x <0, используя диапазон: (Int.min .. <0) .contains (x) в точности эквивалентно. Это значительно медленнее, хотя. Реализация по умолчанию метода содержит (_ :) обходит всю коллекцию, и выполнение цикла девять раз по пять раз в худшем случае недешево.