Swiftでは、==演算子は二つの値の等価性をチェックするために使用されます。この演算子をカスタム型で使用するには、その型がEquatableプロトコルに準拠し、静的関数==を実装する必要があります。
実装は対称的で推移的であるべきです。例えば:
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 } }
自分の型が==を実装していない場合、二つのそれらのインスタンスを比較しようとするとコンパイルエラーが発生します。
質問: 構造体またはクラスがEquatableプロトコルを継承している場合、なぜ時々==演算子を明示的に実装する必要がないのでしょうか?
回答: すべてのプロパティがEquatableに準拠している構造体の場合、Swiftは自動的に==演算子の実装を合成します。しかし、型にEquatableでないプロパティがある場合や、カスタム継承を持つクラスの場合、合成は行われず、手動で演算子を実装する必要があります。
struct Point: Equatable { var x: Int var y: Int // ==の実装は不要、これは自動的に合成される }
物語
あるプロジェクトで、開発者が既に
Equatableに準拠している構造体にUIImage型のプロパティを追加しました。コンパイルエラーが発生したのは、UIImageがEquatableを実装していなかったためで、つまり構造体に自動的に==を合成することができませんでした。解決策は、ロジックにとって重要なプロパティのみを比較するように==演算子を手動で実装することです。
物語
新たなプロパティを構造体に追加したが、それをカスタム
==演算子に追加するのを忘れたためエラーが発生しました。これにより、コレクションを扱う際のロジックが正しくなくなり、ユーザーフィルターにバグが発生しました。
物語
プロジェクトに
Equatableを実装していないカスタムクラスが書かれましたが、それをSetで使用しようとしました。これにより、Setは要素が一意である必要があるため(したがって、Equatableが必要)、ランタイムエラーが発生しました。