Inférieure ou supérieure à Swift instruction switch
Je suis familier avec switch
états Swift, mais vous vous demandez comment faire pour remplacer ce morceau de code avec un switch
:
if someVar < 0 {
//do something
} else if someVar == 0 {
//do something else
} else if someVar > 0 {
//etc
}
- Bien que ce est une question intéressante, je pense que le code à l'aide de l'interrupteur est beaucoup moins lisible que les instructions if. Juste parce que vous pouvez, ne signifie pas que vous devriez.
Vous devez vous connecter pour publier un commentaire.
Voici une approche. En supposant que
someVar
est unInt
ou d'autresComparable
, vous pouvez éventuellement affecter l'opérande à une nouvelle variable. Cela vous permet de portée quand vous le souhaitez à l'aide de lawhere
mot-clé:Cela peut être simplifié un peu:
Vous pouvez également éviter les
where
mot-clé entièrement avec la gamme de correspondance:default: fatalError()
afin de détecter d'éventuelles erreurs de logique tôt.Avec Swift 5, vous pouvez choisir l'une des opérations suivantes commutateur afin de remplacer votre instruction if.
#1 à l'Aide de l'interrupteur avec
PartialRangeFrom
etPartialRangeUpTo
2 à l'Aide du commutateur avec
ClosedRange
etRange
#3 à l'Aide de l'interrupteur avec la clause where
#4 à l'Aide de l'interrupteur avec la clause where et affectation à
_
#5 à l'Aide de l'interrupteur avec
RangeExpression
du protocole de~=(_:_:)
opérateur#6 à l'Aide de l'interrupteur avec
Equatable
du protocole de~=(_:_:)
opérateur#7 à l'Aide de l'interrupteur avec
PartialRangeFrom
,PartialRangeUpTo
etRangeExpression
'scontains(_:)
méthode0.1
jette une erreur fatale car1...
couvre seulement les numéros de 1. Si cette solution ne fonctionne que sivalue
est unInt
mais c'est dangereux parce que si le type de variable modifie la fonctionnalité des pauses sans aucune erreur de compilation.La
switch
déclaration, sous le capot, utilise le~=
de l'opérateur. Donc:Desugars à ceci:
Si vous regardez la norme de référence de la bibliothèque, il peut vous dire exactement ce que le
~=
est surchargé de faire: inclus est gamme assortie, et assimiler pour equatable choses. (Non inclus est enum cas de correspondance, qui est une fonctionnalité du langage, plutôt qu'une fonction dans la prévention des mst lib)Vous verrez que cela ne correspond pas à un droit booléenne sur la gauche. Pour ce genre de comparaisons, vous devez ajouter une instruction where.
À moins que... vous surchargez la
~=
opérateur vous-même. (C'est en général pas recommandé) Une possibilité serait quelque chose comme ceci:Donc qui correspond à une fonction qui retourne un booléen sur la gauche à son paramètre sur la droite. Voici le genre de chose que vous pourriez utiliser pour:
Pour votre cas, vous pouvez avoir une déclaration qui ressemble à ceci:
Mais maintenant vous avez à définir de nouvelles
isNegative
etisPositive
fonctions. À moins que vous la surcharge de certains autres opérateurs...Vous pouvez surcharge normale des opérateurs infixes être au curry préfixe ou un suffixe opérateurs. Voici un exemple:
Ce serait le travail comme ceci:
Combinez cela avec la fonction la plus ancienne, et votre instruction switch peut ressembler à ceci:
Maintenant, vous ne devriez pas utiliser ce genre de chose dans la pratique: c'est un peu louche. Vous êtes (probablement) mieux coller avec la
where
déclaration. Cela dit, l'instruction switch modèle deou
Semble tout de même assez pour qu'il soit utile d'examiner.
Vous pouvez:
Depuis que quelqu'un a déjà posté
case let x where x < 0:
voici une alternative pour oùsomeVar
est unInt
.Et voici une alternative pour où
someVar
est unDouble
:C'est à quoi il ressemble avec des plages de
La
<0
expression ne fonctionne pas (plus?) je me suis donc retrouvé avec ce:Swift 3.0:
X_MAX
a été remplacé par.greatestFiniteMagnitude
, c'est à direDouble.greatestFiniteMagnitude
,CGFloat.greatestFiniteMagnitude
etc. Ainsi, habituellement, vous pouvez simplement fairecase 0..< .greatestFiniteMagnitude
puisque le type desomeVar
est déjà connuvar timeLeft = 100
switch timeLeft {case 0...<=7200: print("ok") default:print("nothing") }
Pourquoi le<=
opérateur n'est pas reconnu? Si je l'écris sans égal, il fonctionne. Mercicase 0...7200:
L'opérateur<=
est un opérateur de comparaison. Dans un interrupteur, vous pouvez uniquement utiliser la gamme des opérateurs (voir docs)someVar
était unInt
et j'ai eu à faireDouble(
someVar)` pour le faire fonctionner...Heureux que Swift 4 traite du problème:
Comme une solution de contournement dans les 3 que j'ai fait:
Fonctionne, mais pas idéal