2015-10-20 1 views
9

Kann mir jemand einen guten Grund geben, warum dies nicht funktioniert:Warum ist gleichzusetzen nicht für optionalen Arrays definiert

let a: [Int]? = [1] 
let b: [Int]? = nil 
a == b 

Das wäre meine vorgeschlagen (wenn unelegant) Lösung sein. Aber es ist trivial, also habe ich das Gefühl, dass ich einen guten Grund vermisse, warum das nicht umgesetzt wird.

func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool { 

    if let lhs = lhs, let rhs = rhs { 
     return lhs == rhs 
    } 
    else if let _ = lhs { 
     return false 
    } 
    else if let _ = rhs { 
     return false 
    } 

    return true 
} 
+0

In der Tat optionaler Wert ist Enum: 'enum OptionalerWert {Fall kein Fall Einige (T)}' kann 'None' oder Ihr Typ sein, wenn Sie einen Wert für ein optionales Array haben, gibt es einen Rückgabetyp, der nicht gleich ist. Kein Rückgabewert im Falle eines zweiten Fehlers kein Typ. In der Tat ist es verschiedene Arten, wenn Sie 'a == b' tun –

Antwort

16

Optionals können nur verglichen werden, wenn der Basiswert umschlossenen Typ gleichzusetzen ist:

public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool 

Jetzt Arrays verglichen sein kann, wenn der Typ Element ist gleichzusetzen:

/// Returns true if these arrays contain the same elements. 
public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool 

aber auch für gleichwertige Typen T, Array<T>entspricht nicht zu dem Equatable Protokoll.

Derzeit dies in Swift nicht möglich ist, siehe zum Beispiel Why can't I make Array conform to Equatable? für eine Diskussion im Apple-Entwickler-Forum. Diese Änderung bei der Umsetzung von SE-0143 Conditional conformances in Swift 4.

Ihre Implementierung korrekt aussieht, hier ist eine mögliche anderes mit dem Schalter/Fall mit Mustervergleich:

func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool { 

    switch (lhs, rhs) { 
    case let (l?, r?) : // shortcut for (.Some(l), .Some(r)) 
     return l == r 
    case (.None, .None): 
     return true 
    default: 
     return false 
    } 
} 
+0

Ah ich sehe, ich erkannte nicht den Grund, dass ich dies vorher mit nicht-optionalen 'Array's konnte nur wegen der globalen Funktionsdeklaration statt eine Erweiterung von 'Array', um sich an" Equatable "anzupassen, wobei die Elemente" Equatable "sind. Was halten Sie von meiner vorgeschlagenen Lösung und warum hätte Apple diese globale Funktion auch nicht mit einbezogen? –

+1

@ScottH: Siehe Aktualisierung. Ich könnte nur über deine letzte Frage spekulieren, aber wenn du sie für Arrays implementierst, was ist dann mit Wörterbüchern, Sets, Sequenzen, ...? –

+0

Es ist eine Menge DRY, das ist ein gültiger Punkt. Dies würde jedoch dem gleichen Muster folgen, das Apple gewählt hat, indem es '==' für nicht-optionale Arrays bereitstellt. Es scheint die beste Option zu sein, bis wir etwas wie 'extension CollectionType: Equatable wo Element: Equatable {...}' machen können. –