J'ai deux variables AnyObject?
que j'aimerais comparer pour l'égalité des références:
var oldValue: AnyObject?
var newValue: AnyObject?
...
if oldValue != newValue {
changed = true
}
Cela ne fonctionne pas bien, car je ne peux apparemment pas comparer directement deux optionnels. Je veux le comportement comme si je comparais id
s en Objective-C, c'est-à-dire:
true
si les deux sont nil
true
si les deux ont une valeur et que les valeurs sont également égalesfalse
autrementExiste-t-il un moyen élégant d’écrire cela dans Swift (idéalement sans écrire une extension personnalisée)?
C'est le meilleur que j'ai trouvé avec:
if !(oldValue != nil && newValue != nil && oldValue == newValue)
Pas très jolie. :(
Vous pouvez utiliser !==
From Le langage de programmation Swift
Swift fournit également deux opérateurs d'identité (
===
et!==
), que vous utilisez pour vérifier si deux références d'objets se rapportent toutes deux à la même instance d'objet.
Quelques bons exemples et explications sont également à Différence entre == et ===
Sur le point @PEEJWEEJ, procédez comme suit: false
var newValue: AnyObject? = "String"
var oldValue: AnyObject? = "String"
if newValue === oldValue {
print("true")
} else {
print("false")
}
En supposant que vous utilisez des entités comparables, cela fonctionnera sur n'importe quoi:
func optionalsAreEqual<T: Comparable>(firstVal: T?, secondVal: T?) -> Bool{
if let firstVal = firstVal, secondVal = secondVal {
return firstVal == secondVal
}
else{
return firstVal == nil && secondVal == nil
}
}
Ce n'est pas exactement court et agréable, mais c'est expressif, clair et réutilisable.
J'ai aimé @ Keith's solution. Mais je pense qu'il n'est pas écrit dans Swift 4, car je ne peux pas le compiler avec le compilateur Swift 4.
J'ai donc converti son code en version Swift 4 ici.
N'oubliez pas que si vous utilisez une version de la langue Swift supérieure à Swift 4.1 , puis cette réponse n'est pas nécessaire car elle fournit cette fonctionnalité par défaut. Vous pouvez consulter ici pour plus de détails.
Version Swift 4 du code de @ Keith:
infix operator ==? : ComparisonPrecedence
func ==? <T: Comparable>(lhs: T?, rhs: T?) -> Bool {
if let lhs = lhs, let rhs = rhs {
return lhs == rhs
} else {
return lhs == nil && rhs == nil
}
}
func ==? <T: AnyObject>(lhs: T?, rhs: T?) -> Bool {
if let lhs = lhs, let rhs = rhs {
return lhs === rhs
} else {
return lhs == nil && rhs == nil
}
}
Je définis un opérateur d'infixe personnalisé avec une fonction pour les types de référence et les types de valeur.
func ==? <T: Comparable>(lhs: T?, rhs: T?) -> Bool {
if let lhs = lhs, rhs = rhs {
return lhs == rhs
} else{ return lhs == nil && rhs == nil }
}
func ==? <T: AnyObject>(lhs: T?, rhs: T?) -> Bool {
if let lhs = lhs, rhs = rhs {
return lhs === rhs
} else{ return lhs == nil && rhs == nil }
}
infix operator ==? { associativity left precedence 130 }
var aString: String? = nil
var bString: String? = nil
print(aString ==? bString) // true
aString = "test"
bString = "test"
print(aString ==? bString) // true
aString = "test2"
bString = "test"
print(aString ==? bString) // false
aString = "test"
bString = nil
print(aString ==? bString) // false
class TT {}
let x = TT()
var aClass: TT? = TT()
var bClass: TT? = TT()
print(aClass ==? bClass) // false
aClass = TT()
bClass = nil
print(aClass ==? bClass) // false
aClass = nil
bClass = nil
print(aClass ==? bClass) // true
aClass = x
bClass = x
print(aClass ==? bClass) // true
Vous pouvez surcharger l'opérateur ==
pour un type Comparable
public func ==<T: SomeType>(lhs: T?, rhs: T?) -> Bool {
switch (lhs,rhs) {
case (.some(let lhs), .some(let rhs)):
return lhs == rhs
case (.none, .none):
return true
default:
return false
}
}
Ou utilisez la comparaison ===
pour AnyObject
, cependant, personnellement, je préférerais ne pas utiliser AnyObject
en premier lieu.