Je connais les switchinstructions de Swift, mais je me demande comment remplacer ce morceau de code par un switch:
if someVar < 0 {
    // do something
} else if someVar == 0 {
    // do something else
} else if someVar > 0 {
    // etc
}Je connais les switchinstructions de Swift, mais je me demande comment remplacer ce morceau de code par un switch:
if someVar < 0 {
    // do something
} else if someVar == 0 {
    // do something else
} else if someVar > 0 {
    // etc
}Réponses:
Voici une approche. En supposant que someVarc'est un Intou un autre Comparable, vous pouvez éventuellement affecter l'opérande à une nouvelle variable. Cela vous permet de l'étendre comme vous le souhaitez en utilisant le wheremot - clé:
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")
}Cela peut être un peu simplifié:
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")
}Vous pouvez également éviter wherecomplètement le mot - clé avec la correspondance de plage:
switch someVar {
case Int.min..<0:
    print("someVar is \(someVar)")
case 0:
    print("someVar is 0")
default:
    print("someVar is \(someVar)")
}default: fatalError()de détecter tôt les éventuelles erreurs de logique.
                    assertionFailuresemble être une option plus sûre, en particulier lorsque vous travaillez en équipe.
                    Avec Swift 5, vous pouvez choisir l'un des commutateurs suivants afin de remplacer votre instruction if.
PartialRangeFrometPartialRangeUpTolet value = 1
switch value {
case 1...:
    print("greater than zero")
case 0:
    print("zero")
case ..<0:
    print("less than zero")
default:
    fatalError()
}ClosedRangeetRangelet 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()
}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()
}_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()
}RangeExpressionl' ~=(_:_:)opérateur du protocolelet value = 1
switch true {
case 1... ~= value:
    print("greater than zero")
case ..<0 ~= value:
    print("less than zero")
default:
    print("zero")
}Equatablel' ~=(_:_:)opérateur du protocolelet 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()
}PartialRangeFrom, PartialRangeUpToet RangeExpressionde » contains(_:)méthodelet value = 1
switch true {
case (1...).contains(value):
    print("greater than zero")
case (..<0).contains(value):
    print("less than zero")
default:
    print("zero")
}0.1renvoie une erreur fatale car 1...ne couvre que les nombres à partir de 1. Cette solution ne fonctionne donc que si valuec'est un Intmais c'est dangereux car si le type de variable change, la fonctionnalité est interrompue sans aucune erreur du compilateur.
                    La switchdéclaration, sous le capot, utilise l' ~=opérateur. Donc ça:
let x = 2
switch x {
case 1: print(1)
case 2: print(2)
case 3..<5: print(3..<5)
default: break
}Desugars à ceci:
if 1          ~= x { print(1) }
else if 2     ~= x { print(2) }
else if 3..<5 ~= x { print(3..<5) }
else {  }Si vous regardez la référence de bibliothèque standard, elle peut vous dire exactement ce que le ~=est surchargé à faire : inclus est la correspondance de plage, et l'équation pour des choses égales. (La correspondance enum-case n'est pas incluse, qui est une fonctionnalité de langage, plutôt qu'une fonction dans la bibliothèque std)
Vous verrez qu'il ne correspond pas à un booléen droit sur le côté gauche. Pour ce genre de comparaisons, vous devez ajouter une instruction where.
Sauf si ... vous surchargez l' ~=opérateur vous-même. (Ce n'est généralement pas recommandé) Une possibilité serait quelque chose comme ceci:
func ~= <T> (lhs: T -> Bool, rhs: T) -> Bool {
  return lhs(rhs)
}Cela correspond donc à une fonction qui renvoie un booléen à gauche à son paramètre à droite. Voici le genre de chose pour laquelle vous pouvez l'utiliser:
func isEven(n: Int) -> Bool { return n % 2 == 0 }
switch 2 {
case isEven: print("Even!")
default:     print("Odd!")
}Pour votre cas, vous pourriez avoir une déclaration qui ressemble à ceci:
switch someVar {
case isNegative: ...
case 0: ...
case isPositive: ...
}Mais maintenant, vous devez définir de nouveaux isNegativeetisPositive fonctions. Sauf si vous surchargez plus d'opérateurs ...
Vous pouvez surcharger les opérateurs d'infixe normaux pour qu'ils soient des opérateurs de préfixe curry ou de suffixe. Voici un exemple:
postfix operator < {}
postfix func < <T : Comparable>(lhs: T)(_ rhs: T) -> Bool {
  return lhs < rhs
}Cela fonctionnerait comme ceci:
let isGreaterThanFive = 5<
isGreaterThanFive(6) // true
isGreaterThanFive(5) // falseCombinez cela avec la fonction précédente, et votre instruction switch peut ressembler à ceci:
switch someVar {
case 0< : print("Bigger than 0")
case 0  : print("0")
default : print("Less than 0")
}Maintenant, vous ne devriez probablement pas utiliser ce genre de chose dans la pratique: c'est un peu douteux. Vous feriez (probablement) mieux de vous en tenir à la wheredéclaration. Cela dit, le modèle d'instruction switch de
switch x {
case negative:
case 0:
case positive:
}ou
switch x {
case lessThan(someNumber):
case someNumber:
case greaterThan(someNumber):
}Cela semble assez courant pour que cela vaille la peine d'être considéré.
Puisque quelqu'un a déjà posté case let x where x < 0:ici, c'est une alternative pour où someVarest un fichier Int.
switch someVar{
case Int.min...0: // do something
case 0: // do something
default: // do something
}Et voici une alternative pour où someVar est un Double:
case -(Double.infinity)...0: // do something
// etcVoici à quoi ça ressemble avec les gammes
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"
}L' <0expression ne fonctionne pas (plus?) Alors j'ai fini avec ceci:
Swift 3.0:
switch someVar {
    case 0:
        // it's zero
    case 0 ..< .greatestFiniteMagnitude:
        // it's greater than zero
    default:
        // it's less than zero
    }X_MAXa été remplacé par .greatestFiniteMagnitude, c'est-à-dire Double.greatestFiniteMagnitude, CGFloat.greatestFiniteMagnitudeetc. Donc, généralement, vous pouvez le faire case 0..< .greatestFiniteMagnitudepuisque le type de someVarest déjà connu
                    var timeLeft = 100 switch timeLeft {case 0...<=7200:             print("ok")  default:print("nothing") }Pourquoi l'   <=opérateur n'est-il pas reconnu? Si je l'écris sans égal, cela fonctionne. Merci
                    case 0...7200:L'opérateur <=est un opérateur de comparaison. Dans un commutateur, vous ne pouvez utiliser que des opérateurs de plage (voir la documentation)
                    someVarun Intet je devais faire Double(someVar) `pour le faire fonctionner ...
                    Heureux que Swift 4 résout le problème:
Comme solution de contournement dans 3, j'ai fait:
switch translation.x  {
case  0..<200:
    print(translation.x, slideLimit)
case  -200..<0:
    print(translation.x, slideLimit)
default:
    break
}Fonctionne mais pas idéal