Swift-Gleichheitsoperator für verschachtelte Arrays

Warum kann die letzte statement nicht mit dem Fehler kompiliert werden: Der Binary operator '==' cannot be applied to two '[[Simple]]' operands , und es gibt eine Möglichkeit, die Simple Struktur zu ändern oder den Operator == zu erweitern in der Lage sein, Gleichheitsprüfungen für verschachtelte Arrays (oder Wörterbücher) durchzuführen?

 var i1: [Int] = [1] var i2: [Int] = [1] i1 == i2 // -> true var i3: [[Int]] = [[1], [2]] var i4: [[Int]] = [[1], [2]] i3 == i4 // -> true struct Simple: Equatable, Hashable { let message: String var hashValue: Int { return message.hashValue } } func ==(lhs: Simple, rhs: Simple) -> Bool { return lhs.message == rhs.message } var a: [Simple] = [Simple(message: "a")] var b: [Simple] = [Simple(message: "a")] a == b // -> true var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]' operands 

Update: Bedingte Konformität wurde in Swift 4.1 implementiert . Bestimmtes:

Die Standardbibliothekstypen Optional, Array und Dictionary entsprechen jetzt dem Equatable-Protokoll, wenn ihre Elementtypen Equatable entsprechen. …

(vom schnellen CHANGELOG ).

Beliebig verschachtelte Arrays von Equatable Elementen sind jetzt Equatable und können mit == verglichen werden. Dein Code

 var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] x == y 

kompiliert in Xcode 9.3, wenn Simple ist.


(Alte Antwort 🙂 Der Grund ist ähnlich wie in Warum ist Equatable nicht für optionale Arrays definiert . Arrays können mit == verglichen werden, wenn der Elementtyp gleich ist:

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

Deshalb

 var a: [Simple] = [Simple(message: "a")] var b: [Simple] = [Simple(message: "a")] a == b // -> true 

kompiliert.

Aber selbst für gleichwertige Typen T Array nicht dem Equatable Protokoll, vergleiche Warum kann ich Array nicht Equatable anpassen? . Daher, in

 var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]' operands 

x und y sind Arrays mit dem Elementtyp [Simple] die nicht dem Equatable Protokoll entsprechen, und es gibt keinen passenden Operator == .

Sie könnten einen generischen Operator == für einfach verschachtelte Arrays definieren

 func == (lhs: [[Element]], rhs: [[Element]]) -> Bool { return lhs.count == rhs.count && !zip(lhs, rhs).contains {$0 != $1 } } 

oder einfacher (wie von @kennytm vorgeschlagen):

 func == (lhs: [[Element]], rhs: [[Element]]) -> Bool { return lhs.elementsEqual(rhs, by: ==) } 

Dadurch wird x == y kompiliert und funktioniert wie erwartet. Gegenwärtig scheint es keinen Weg zu geben, einen == Operator auf beliebig verschachtelten Arrays zu definieren.

Sie können es tun, indem Sie eine == function wie folgt implementieren:

 func == (lhs: [[Simple]], rhs: [[Simple]]) -> Bool { //your code }