switch for example swift switch-statement

for - uiswitch swift



Menor o mayor que en la declaración de cambio rápido (8)

Estoy familiarizado con las declaraciones de switch 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 }


Aquí hay un enfoque. Suponiendo que someVar es un Int u otro Comparable , puede asignar opcionalmente el operando a una nueva variable. Esto le permite abarcarlo como quiera usando la palabra clave where :

var someVar = 3 switch someVar { case let x where x < 0: print("x is /(x)") case let x where x == 0: print("x is /(x)") case let x where x > 0: print("x is /(x)") default: print("this is impossible") }

Esto se puede simplificar un poco:

switch someVar { case _ where someVar < 0: print("someVar is /(someVar)") case 0: print("someVar is 0") case _ where someVar > 0: print("someVar is /(someVar)") default: print("this is impossible") }

También puede evitar la palabra clave where completo con la coincidencia de rango:

switch someVar { case Int.min..<0: print("someVar is /(someVar)") case 0: print("someVar is 0") default: print("someVar is /(someVar)") }


Así es como se ve con los rangos

switch average { case 0..<40: //greater or equal than 0 and less than 40 return "T" case 40..<55: //greater or equal than 40 and less than 55 return "D" case 55..<70: //greater or equal than 55 and less than 70 return "P" case 70..<80: //greater or equal than 70 and less than 80 return "A" case 80..<90: //greater or equal than 80 and less than 90 return "E" case 90...100: //greater or equal than 90 and less or equal than 100 return "O" default: return "Z" }


Con Swift 5, puede elegir uno de los siguientes interruptores para reemplazar su declaración if.

# 1 Usando el interruptor con PartialRangeFrom y PartialRangeUpTo

let value = 1 switch value { case 1...: print("greater than zero") case 0: print("zero") case ..<0: print("less than zero") default: fatalError() }

# 2 Usando el interruptor con ClosedRange y Range

let value = 1 switch value { case 1 ... Int.max: print("greater than zero") case Int.min ..< 0: print("less than zero") case 0: print("zero") default: fatalError() }

# 3 Usando el interruptor con la cláusula where

let value = 1 switch value { case let val where val > 0: print("/(val) is greater than zero") case let val where val == 0: print("/(val) is zero") case let val where val < 0: print("/(val) is less than zero") default: fatalError() }

# 4 Uso de switch con cláusula where y asignación a _

let value = 1 switch value { case _ where value > 0: print("greater than zero") case _ where value == 0: print("zero") case _ where value < 0: print("less than zero") default: fatalError() }

# 5 Uso del interruptor con el RangeExpression ~=(_:_:) del protocolo RangeExpression

let value = 1 switch true { case 1... ~= value: print("greater than zero") case ..<0 ~= value: print("less than zero") default: print("zero") }

# 6 Usando el interruptor con el Equatable ~=(_:_:) del protocolo Equatable

let value = 1 switch true { case value > 0: print("greater than zero") case value < 0: print("less than zero") case 0 ~= value: print("zero") default: fatalError() }

# 7 Usando el interruptor con PartialRangeFrom , PartialRangeUpTo y RangeExpression ''s contains(_:) método contains(_:)

let value = 1 switch true { case (1...).contains(value): print("greater than zero") case (..<0).contains(value): print("less than zero") default: print("zero") }


Dado que alguien ya ha publicado el case let x where x < 0: aquí hay una alternativa para donde someVar es un Int .

switch someVar{ case Int.min...0: // do something case 0: // do something default: // do something }

Y aquí hay una alternativa para donde someVar es un Double :

case -(Double.infinity)...0: // do something // etc


La expresión <0 no funciona (¿ya?), Así que terminé con esto:

Swift 3.0:

switch someVar { case 0: // it''s zero case 0 ..< .greatestFiniteMagnitude: // it''s greater than zero default: // it''s less than zero }


La instrucción switch , debajo del capó, usa el operador ~= . Así que esto:

let x = 2 switch x { case 1: print(1) case 2: print(2) case 3..<5: print(3..<5) default: break }

Desugar a esto:

if 1 ~= x { print(1) } else if 2 ~= x { print(2) } else if 3..<5 ~= x { print(3..<5) } else { }

Si nos fijamos en la referencia de la biblioteca estándar, puede decirle exactamente para qué está sobrecargado el ~= : 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:

func ~= <T> (lhs: T -> Bool, rhs: T) -> Bool { return lhs(rhs) }

De modo que 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:

func isEven(n: Int) -> Bool { return n % 2 == 0 } switch 2 { case isEven: print("Even!") default: print("Odd!") }

Para su caso, es posible que tenga una declaración que se vea así:

switch someVar { case isNegative: ... case 0: ... case isPositive: ... }

Pero ahora debe definir las nuevas funciones isNegative e isPositive . 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:

postfix operator < {} postfix func < <T : Comparable>(lhs: T)(_ rhs: T) -> Bool { return lhs < rhs }

Esto funcionaría así:

let isGreaterThanFive = 5< isGreaterThanFive(6) // true isGreaterThanFive(5) // false

Combine eso con la función anterior, y su declaración de cambio puede verse así:

switch someVar { case 0< : print("Bigger than 0") case 0 : print("0") default : print("Less than 0") }

Ahora, probablemente no deberías usar este tipo de cosas en la práctica: es un poco dudoso. Es (probablemente) mejor seguir con la declaración where . Dicho esto, el patrón de declaración de cambio de

switch x { case negative: case 0: case positive: }

o

switch x { case lessThan(someNumber): case someNumber: case greaterThan(someNumber): }

Parece lo suficientemente común como para que valga la pena considerarlo.


Me alegro de que Swift 4 aborde el problema: como solución en 3 hice:

switch translation.x { case 0..<200: print(translation.x, slideLimit) case -200..<0: print(translation.x, slideLimit) default: break }

Funciona pero no es ideal


Usted puede:

switch true { case someVar < 0: print("less than zero") case someVar == 0: print("eq 0") default: print("otherwise") }