Можно ли использовать оператор диапазона с инструкцией if в Swift?

Можно ли использовать оператор диапазона ... и ..< с инструкцией if. Maye что-то вроде этого:

let statusCode = 204
if statusCode in 200 ..< 299 {
  NSLog("Success")
}

Ответ 1

Вы можете использовать оператор "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-statement. См. Также Swift 2 - Соответствие шаблону в "if" .

Ответ 2

Эта версия кажется более читаемой, чем сопоставление с образцом:

if (200 ... 299).contains(statusCode) {
    print("Success")
}

Ответ 3

Это старый поток, но мне кажется, что мы слишком задумываемся об этом. Мне кажется, лучший ответ - просто

if statusCode >= 200 && statusCode <= 299

Нет

if 200 > statusCode > 299

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

Ответ 4

Я также предлагал оператор Range.contains(), пока не обнаружил, что его реализация неэффективна - https://oleb.net/blog/2015/09/swift-ranges-and-intervals/

Мы можем представить условие x < 0 с использованием диапазона: (Int.min.. < 0). Содержит (x) в точности эквивалентно. Он значительно медленнее, хоть. По умолчанию реализация содержит (_:) обходит целую коллекцию и выполнение цикла в девять квинтиллионов раз в худший случай не дешев.