2016-03-17 9 views
11

Mam dwa AnyObject? zmienne, które chciałbym porównać dla równości odniesienia:Najbardziej eleganckim sposobem porównać dwa ewentualne, w Swift

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

to nie działa choć, jak ja widocznie nie można porównać dwa składniki ewentualne bezpośrednio. Chcę zachowanie jakbym porównując id S w Objective-C, to jest:

  • true jeśli oba są nil
  • true jeśli oba mają wartość i wartości są także równe
  • false inaczej

Czy istnieje elegancki sposób na napisanie tego w Swift (najlepiej bez pisania niestandardowego rozszerzenia)?

Jest to najlepszy jaki wymyślić:

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

niezbyt ładna. :(

+1

Możesz użyć '! ==' zobacz http://stackoverflow.com/questions/24002819/difference-between-and dla odniesienia. – sbarow

+0

Czy to naprawdę jest ?! Ciągle zapominam o tym operatorze! – devios1

+0

@sbarow Myślę, że masz to właściwie. Opublikuj odpowiedź, jeśli chcesz rep. – devios1

Odpowiedz

9

Można użyć. !==

Od Swift Programming Language

Swift udostępnia również dwa operatory tożsamości (=== i !==), których używa się do testowania dwóch odwołań do obiektów zarówno w odniesieniu do tej samej instancji obiektu.

Niektóre dobre przykłady i objaśnienia są również w Difference between == and ===

na punkt @PEEJWEEJ, wykonując następujące czynności spowoduje false

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

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

FYI, myślę, że jeśli oldValue i newValue są obiektami, === zawsze będzie fałszywe, chyba że faktycznie są ustawione na ten sam obiekt. – PeejWeej

+0

@PEEJWEEJ yip thats correct, dodano przykład. – sbarow

9

Zakładając, że używasz podmioty porównywalne, to będzie działać na niczym:

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

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

To nie jest dokładnie to krótkie i słodkie, ale to wyraziste, jasne i wielokrotnego użytku

+0

Chociaż nie jest to dokładnie to, czego szukałem, dziękuję za umieszczenie tego w przypadku, gdy inni szukają porównanie bez odniesienia. – devios1

1

zdefiniować operator zwyczaj Infix z funkcją zarówno w odniesieniu typy i typy wartości.

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

Czy to nie wystarcza? – Toad