2016-03-17 18 views
11

ho due AnyObject? variabili che vorrei confrontare per l'uguaglianza di riferimento:modo più elegante per confrontare due optional a Swift

var oldValue: AnyObject? 
var newValue: AnyObject? 
... 
if oldValue != newValue { 
    changed = true 
} 

Questo non funziona se, come io a quanto pare non posso paragonare direttamente due optionals. Voglio che il comportamento come se stessi paragonando id s in Objective-C, vale a dire:

  • true se entrambi sono nil
  • true se entrambi hanno un valore ed i valori sono uguali
  • false altrimenti

C'è un modo elegante per scrivere questo in Swift (idealmente senza dover scrivere un'estensione personalizzata)?

Questo è il migliore che è venuta in mente:

if !(oldValue != nil && newValue != nil && oldValue == newValue) 

Non molto carina. :(

+1

È possibile utilizzare '! ==' vedere http://stackoverflow.com/questions/24002819/difference-tra i- e per riferimento. – sbarow

+0

È davvero così ?! Continuo a dimenticare quell'operatore! – devios1

+0

@sbarow Penso che tu l'abbia preso davvero. Pubblica la risposta se vuoi il rappresentante. – devios1

risposta

9

è possibile utilizzare. !==

Da La Swift linguaggio di programmazione

Swift fornisce anche due operatori di identità (=== e !==), che vengono utilizzati per verificare se due riferimenti di oggetti si riferiscono entrambi alla stessa istanza di oggetto.

Alcuni buoni esempi e le spiegazioni sono anche a Difference between == and ===

Sul punto @PEEJWEEJ, facendo quanto segue si tradurrà in false

var newValue: AnyObject? = "String" 
var oldValue: AnyObject? = "String" 

if newValue === oldValue { 
    print("true") 
} else { 
    print("false") 
} 
+3

FYI, penso che se oldValue e newValue sono oggetti, === sarà sempre falso a meno che non siano effettivamente impostati sullo stesso oggetto. – PeejWeej

+0

@PEEJWEEJ è corretto, aggiunto un esempio. – sbarow

9

si Supponendo che sta utilizzando le entità comparabili, questo funzionerà su qualsiasi cosa:

func optionalsAreEqual<T: Comparable>(firstVal: T?, secondVal: T?) -> Bool{ 

    if let firstVal = firstVal, secondVal = secondVal { 
     return firstVal == secondVal 
    } 
    else{ 
     return firstVal == nil && secondVal == nil 
    } 
} 

Non è esattamente breve e dolce, ma è espressivo, chiara, e riutilizzabile

+0

Anche se non è esattamente quello che stavo cercando, grazie per la pubblicazione di questo nel caso in cui gli altri sono alla ricerca di un confronto non di riferimento. – devios1

1

definisco un operatore infisso personalizzato con una funzione sia di riferimento tipi e tipi di valore.

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 
+0

Non è più che sufficiente? – Toad

Problemi correlati