Estoy familiarizado con las switch
declaraciones en Swift, pero me pregunto cómo reemplazar este fragmento de código con un switch
:
if someVar < 0 {
// do something
} else if someVar == 0 {
// do something else
} else if someVar > 0 {
// etc
}
swift
switch-statement
Pieter
fuente
fuente
Respuestas:
Aquí hay un enfoque. Suponiendo que
someVar
es unoInt
u otroComparable
, opcionalmente puede asignar el operando a una nueva variable. Esto le permite definir el alcance como desee con lawhere
palabra clave:Esto se puede simplificar un poco:
También puede evitar la
where
palabra clave por completo con la coincidencia de rango:fuente
default: fatalError()
detectar posibles errores lógicos temprano.assertionFailure
parece ser una opción más segura, especialmente cuando se trabaja en equipo.Con Swift 5, puede elegir uno de los siguientes interruptores para reemplazar su declaración if.
# 1 Usando el interruptor con
PartialRangeFrom
yPartialRangeUpTo
# 2 Usando el interruptor con
ClosedRange
yRange
# 3 Usando el interruptor con la cláusula where
# 4 Uso de switch con cláusula where y asignación a
_
# 5 Usando el interruptor con
RangeExpression
el~=(_:_:)
operador del protocolo# 6 Usando el interruptor con
Equatable
el~=(_:_:)
operador del protocolo# 7 Usando el interruptor con
PartialRangeFrom
,PartialRangeUpTo
yRangeExpression
elcontains(_:)
método defuente
0.1
arroja un error fatal porque1...
cubre solo números del 1. Por lo tanto, esta solución solo funciona sivalue
es unInt
pero eso es peligroso porque si el tipo de variable cambia la funcionalidad se rompe sin ningún error del compilador.La
switch
declaración, debajo del capó, utiliza el~=
operador. Así que esto:Desugar a esto:
Si observa la referencia de la biblioteca estándar, puede decirle exactamente para qué
~=
está sobrecargada : se incluye la coincidencia de rango y la ecuación para cosas equiparables. (No se incluye la coincidencia de mayúsculas y minúsculas, que es una característica del lenguaje, en lugar de una función en la biblioteca estándar)Verá que no coincide con un booleano recto en el lado izquierdo. Para ese tipo de comparaciones, debe agregar una declaración where.
A menos que ... sobrecargues el
~=
operador tú mismo. (Esto generalmente no se recomienda) Una posibilidad sería algo como esto:Entonces, coincide con una función que devuelve un valor booleano a la izquierda a su parámetro a la derecha. Este es el tipo de cosas para las que podría usarlo:
Para su caso, es posible que tenga una declaración que se vea así:
Pero ahora tienes que definir nuevas
isNegative
yisPositive
funciones. A menos que sobrecargue algunos operadores más ...Puede sobrecargar los operadores de infijo normales para ser operadores de prefijo o postfix curry. Aquí hay un ejemplo:
Esto funcionaría así:
Combine eso con la función anterior, y su declaración de cambio puede verse así:
Ahora, probablemente no deberías usar este tipo de cosas en la práctica: es un poco dudoso. Es (probablemente) mejor seguir con la
where
declaración. Dicho esto, el patrón de declaración de cambio deo
Parece lo suficientemente común como para que valga la pena considerarlo.
fuente
Usted puede:
fuente
Dado que alguien ya ha publicado
case let x where x < 0:
aquí, es una alternativa para dóndesomeVar
es unInt
.Y aquí hay una alternativa de dónde
someVar
es unDouble
:fuente
Así es como se ve con los rangos
fuente
La
<0
expresión no funciona (¿ya?), Así que terminé con esto:Swift 3.0:
fuente
X_MAX
ha sido reemplazado por.greatestFiniteMagnitude
, es decirDouble.greatestFiniteMagnitude
,CGFloat.greatestFiniteMagnitude
etc. Por lo general, puede hacerlocase 0..< .greatestFiniteMagnitude
ya que el tipo desomeVar
ya se conocevar timeLeft = 100
switch timeLeft {case 0...<=7200: print("ok") default:print("nothing") }
¿Por qué<=
no se reconoce al operador? Si lo escribo sin igual funciona. Graciascase 0...7200:
el operador<=
es un operador de comparación. En un switch solo puedes usar operadores de rango (ver documentos)someVar
eraInt
y tenía que hacerDouble(
algoVar) `para que funcione ...Me alegra que Swift 4 aborde el problema:
Como solución en 3 hice:
Funciona pero no es ideal
fuente