W Swift operator == służy do sprawdzania równości dwóch wartości. Aby operator ten mógł być używany z typami użytkownika, typ musi implementować protokół Equatable i realizować statyczną funkcję ==.
Implementacja musi być symetryczna i tranzystywna. Przykład:
struct Person: Equatable { let name: String let age: Int static func ==(lhs: Person, rhs: Person) -> Bool { return lhs.name == rhs.name && lhs.age == rhs.age } }
Należy pamiętać, że jeśli twój typ nie implementuje ==, to próba porównania dwóch takich instancji zakończy się błędem kompilacji.
Pytanie: Jeśli struktura lub klasa dziedziczy po protokole Equatable, dlaczego czasami operator == nie musi być jawnie implementowany?
Odpowiedź: Dla struktur, wszystkie właściwości, które również są zgodne z Equatable, Swift automatycznie syntetyzuje implementację operatora ==. Ale jeśli w typie są właściwości, które nie są Equatable, lub typ to klasa z niestandardowym dziedziczeniem, synteza się nie odbędzie i będzie konieczne ręczne zaimplementowanie operatora.
struct Point: Equatable { var x: Int var y: Int // Implementacja == nie jest potrzebna, jest automatycznie syntetyzowana }
Historia
W jednym projekcie programista dodał właściwość typu
UIImagedo struktury, która już spełniała kryteriaEquatable. Błąd kompilacji wystąpił, ponieważUIImagenieImplementujeEquatable, co oznacza, że dla struktury nie mogło zostać automatycznie wygenerowane==. Rozwiązanie — ręczna implementacja operatora==, porównując tylko istotne dla logiki właściwości.
Historia
Błąd wystąpił po dodaniu nowej właściwości do struktury, ale zapomniano dodać jej porównanie w użytkowym operatorze
==. Doprowadziło to do nieprawidłowej logiki w pracy z kolekcjami i błędów w użytkowym filtrze.
Historia
W projekcie stworzono niestandardową klasę bez implementacji
Equatable, ale próbowano ją użyć w Set. Doprowadziło to do błędu runtime, ponieważ Set wymaga, aby elementy były unikalne (a więcEquatable).