web-dev-qa-db-fra.com

Puis-je utiliser l'opérateur de plage avec l'instruction if dans Swift?

Est-il possible d'utiliser l'opérateur de plage ... et ..< avec l'instruction if? Maye quelque chose comme ça:

let statusCode = 204
if statusCode in 200 ..< 299 {
  NSLog("Success")
}
167
Jimmy

Vous pouvez utiliser l'opérateur "pattern-match" ~=:

if 200 ... 299 ~= statusCode {
    print("success")
}

Ou une instruction switch avec un motif d'expression (qui utilise l'opérateur de correspondance de motif en interne):

switch statusCode {
case 200 ... 299:
    print("success")
default:
    print("failure")
}

Notez que ..< dénote une plage qui omet la valeur supérieure, vous voulez donc probablement 200 ... 299 ou 200 ..< 300.

Informations complémentaires: Lorsque le code ci-dessus est compilé dans Xcode 6.3 avec l'optimisation activée, puis pour le test

if 200 ... 299 ~= statusCode

en fait, aucun appel de fonction n'est généré, seulement trois instructions d'assemblage:

addq    $-200, %rdi
cmpq    $99, %rdi
ja  LBB0_1

c'est exactement le même code d'assemblage qui est généré pour

if statusCode >= 200 && statusCode <= 299

Vous pouvez vérifier cela avec

 xcrun -sdk macosx swiftc -O -emit-Assembly main.Swift 

À partir de Swift 2, cela peut être écrit ainsi:

if case 200 ... 299 = statusCode {
    print("success")
}

en utilisant la correspondance de modèle récemment introduite pour les instructions if. Voir aussi Swift 2 - Pattern matching in "if" .

372
Martin R

Cette version semble être plus lisible que le filtrage par motif:

if (200 ... 299).contains(statusCode) {
    print("Success")
}
85
Serhii Yakovenko

C'est un vieux fil, mais il me semble que nous y réfléchissons trop. Il me semble que la meilleure réponse est juste

if statusCode >= 200 && statusCode <= 299

Il n'y a pas

if 200 > statusCode > 299

je connais cette forme et les autres solutions suggérées font des appels de fonction, qui seront plus lents et plus difficiles à lire. La méthode de correspondance de modèle est une astuce utile à connaître, mais semble être un mauvais ajustement pour ce problème

8
Duncan C

Je voulais vérifier les erreurs 4xx sauf 401. Voici le code:

let i = 401

if 400..<500 ~= i, i != 401 {
    print("yes")
} else {
    print("NO")
}
3
abhimuralidharan

J'ai également préféré l'opérateur Range .contains () jusqu'à ce que son implémentation soit inefficace - https://oleb.net/blog/2015/09/Swift-ranges-and-intervals/

Nous pouvons représenter la condition x <0 en utilisant une plage: (Int.min .. <0) .contains (x) est exactement équivalent. C'est beaucoup plus lent, cependant. L'implémentation par défaut de contain (_ :) parcourt toute la collection et l'exécution d'une boucle neuf fois sur quinze dans le pire des cas n'est pas bon marché.

1
Entro