2017-06-28 4 views
2

Swift 3, ceci est une erreur de compilation, si j'utilise > ou <Pourquoi les opérateurs supérieurs ou inférieurs à Swift ne peuvent-ils pas comparer les options lorsque les opérateurs d'égalité le peuvent?

let a: Int? 
guard a > 0 else {return} 
guard a < 0 else {return} 

Erreur de compilation:

Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?


Mais il est correct si je compare avec == ou !=

let a: Int? 
guard a == 0 else {return} 
guard a != 0 else {return} 
+3

À quoi s'attendriez-vous que 'nil <0' évalue? Que diriez-vous de '-1 Hamish

+1

Comparer https://stackoverflow.com/q/39251005/2976878 – Hamish

+1

Proposition: [Supprimer Opérateurs de comparaison optionnels] (https://github.com/apple/swift-evolution/blob/master/proposals/0121-remove-optional -comparison-operators.md). En outre, cela doit être un dupe. – JAL

Répondre

1

Il est parfaitement logique pour l'égali opérateur ty pour soutenir optionals, car il est tout à fait clair que pour une variable valeur entière i:

  • nil == nil
  • nil != i
  • i != nil
  • i == i si et seulement si leurs valeurs sont les mêmes

D'autre part, il ne est pas clair comment la comparaison à nil devrait agir:

Est-ce que i est inférieur à nil?

  • Si je veux trier un tableau afin que tous les nil s sortent à la fin, alors je veux i être inférieur à nil.
  • Mais si je veux trier un tableau de sorte que tous les nil sortent au début, alors je voudrais que i soit supérieur à nil.

Étant donné que l'un ou l'autre de ces éléments est également valide, il ne serait pas logique que la bibliothèque standard favorise l'un par rapport à l'autre. C'est au programmeur de mettre en œuvre la comparaison qui a du sens pour leur cas d'utilisation.

Voici une mise en œuvre de jouet qui génère un opérateur de comparaison à la suite les deux cas:

func nilComparitor<T: Comparable>(nilIsLess: Bool) -> (T?, T?) -> Bool { 
    return { 
     switch ($0, $1) { 
      case (nil, nil): return true 
      case (nil, _?): return nilIsLess 
      case (_?, nil): return !nilIsLess 
      case let (a?, b?): return a < b 
     } 
    } 
} 

let input = (0...10).enumerated().map { 
    $0.offset % 2 == 0 ? Optional($0.element) : nil 
} 

print("Input:", input) 
print("\r\n\r\n\r\n") 
print("nil is less: ", input.sorted(by: nilComparitor(nilIsLess: true))) 
print("\r\n\r\n\r\n") 
print("nil is more: ", input.sorted(by: nilComparitor(nilIsLess: false))) 

Sortie:

Input: [Optional(0), nil, Optional(2), nil, Optional(4), nil, Optional(6), nil, Optional(8), nil, Optional(10)]

nil is less: [nil, nil, nil, nil, nil, Optional(0), Optional(2), Optional(4), Optional(6), Optional(8), Optional(10)]

nil is more: [Optional(0), Optional(2), Optional(4), Optional(6), Optional(8), Optional(10), nil, nil, nil, nil, nil]

0

En effet, Int et Int? sont 2 choses différentes.

Selon le documentation, Int a pour < et surcharges > et d'autres opérateurs, tout en option ne dispose que pour == et surcharges !=, voir la documentation on Optional, la section parle de La comparaison des valeurs optionnelles.

0

L'égalité optionnelle fonctionne logiquement, contrairement à la comparaison.

  • 5 == 5 = true
  • 5 == néant = false
  • 5 == 6 = false
  • néant == nil = true

Les tous sens, mais ceux-ci ne le font pas:

  • 6> 5 = true
  • 5> 5 = faux
  • 5> nil = ??
  • nul> 5 = ??

Ce type de comparaison n'a pas de réponse simple, et cette réponse ne sera pas la même selon le cas d'utilisation.