¿Es posible usar el operador de rango ...
y ..<
con la instrucción if? Maye algo como esto:
let statusCode = 204
if statusCode in 200 ..< 299 {
NSLog("Success")
}
¿Es posible usar el operador de rango ...
y ..<
con la instrucción if? Maye algo como esto:
let statusCode = 204
if statusCode in 200 ..< 299 {
NSLog("Success")
}
Respuestas:
Puede usar el operador "coincidencia de patrones" ~=
:
if 200 ... 299 ~= statusCode {
print("success")
}
O una declaración de cambio con un patrón de expresión (que utiliza el operador de coincidencia de patrones internamente):
switch statusCode {
case 200 ... 299:
print("success")
default:
print("failure")
}
Tenga en cuenta que ..<
denota un rango que omite el valor superior, por lo que probablemente desee
200 ... 299
o 200 ..< 300
.
Información adicional: cuando el código anterior se compila en Xcode 6.3 con las optimizaciones activadas, entonces para la prueba
if 200 ... 299 ~= statusCode
en realidad no se genera ninguna llamada de función, solo tres instrucciones de ensamblaje:
addq $-200, %rdi
cmpq $99, %rdi
ja LBB0_1
este es exactamente el mismo código de ensamblado que se genera para
if statusCode >= 200 && statusCode <= 299
Puedes verificar eso con
xcrun -sdk macosx swiftc -O -emit-assembly main.swift
A partir de Swift 2, esto se puede escribir como
if case 200 ... 299 = statusCode {
print("success")
}
utilizando la coincidencia de patrones recientemente introducida para sentencias if. Consulte también Swift 2: coincidencia de patrones en "if" .
func ~= (Range<A>, A) -> Bool
se llama a una función de biblioteca . Me gustaría suponer que esta función trabaja con O (1).
xcrun -sdk macosx swift -emit-assembly main.swift
e inspeccioné el código de ensamblaje. Luego solía xcrun swift-demangle ...
desorganizar el nombre de la función llamada. - Desafortunadamente, Xcode aún no puede crear código de ensamblaje para archivos Swift, quizás funcione en una versión posterior.
Esta versión parece ser más legible que la coincidencia de patrones:
if (200 ... 299).contains(statusCode) {
print("Success")
}
Este es un hilo viejo, pero me parece que estamos pensando demasiado en esto. Me parece que la mejor respuesta es solo
if statusCode >= 200 && statusCode <= 299
No hay
if 200 > statusCode > 299
que yo conozco, y las otras soluciones sugeridas están haciendo llamadas a funciones, que son más difíciles de leer y pueden ser más lentas de ejecutar. El método de coincidencia de patrones es un truco útil para conocer, pero parece ser un mal ajuste para este problema.
Personalmente, considero que el operador de coincidencia de patrones es horrible, y deseo que el compilador admita la if x in 1...100
sintaxis. Eso es muuuucho más intuitivo y fácil de leer queif 1...100 ~= x
if 200 ... 299 ~= statusCode
, sin llamada de función :)
if 200 ... 299 ~= statusCode
da el mismo código de ensamblaje queif statusCode >= 200 && statusCode <= 299
Quería verificar los errores 4xx excepto 401. Aquí está el código:
let i = 401
if 400..<500 ~= i, i != 401 {
print("yes")
} else {
print("NO")
}
También preferí el operador Range .contains (), hasta que descubrí que su implementación es ineficiente - https://oleb.net/blog/2015/09/swift-ranges-and-intervals/
Podemos representar la condición x <0 usando un rango: (Int.min .. <0) .contains (x) es exactamente equivalente. Sin embargo, es mucho más lento. La implementación predeterminada de contiene (_ :) atraviesa toda la colección, y ejecutar un bucle nueve quintillones de veces en el peor de los casos no es barato.