私は以下を持っていますProtocol
:
protocol Cacheable {
//....//
func identifier() -> String
}
Cacheable
でEquatableを実装できますか?
私が次のことをしたとき:
extension Cacheable: Equatable {}
func ==(lhs:Cacheable,rhs:Cacheable) -> Bool {
return lhs.identifier() == rhs.identifier()
}
このエラーメッセージが表示されました:プロトコルCacheable
の拡張には継承句を含めることはできません
Cacheable
sを比較できるようにするprotocol Cacheable: Equatable {
//....//
func identifier() -> String
}
func ==<T : Cacheable>(lhs: T, rhs: T) -> Bool {
return lhs.identifier() == rhs.identifier()
}
これが最も簡単なソリューションです。
同じタイプの2つのCacheable
オブジェクトのみを比較できます。これは、以下のコードが失敗することを意味し、それを修正するにはAnimal
をCacheable
に準拠させる必要があります。
class Animal {
}
class Dog: Animal,Cacheable {
func identifier() -> String {
return "object"
}
}
class Cat: Animal,Cacheable {
func identifier() -> String {
return "object"
}
}
let a = Dog()
let b = Cat()
a == b //such comparison is not allowed
Cacheable
sを許可しますprotocol Cacheable:Equatable {
//....//
func identifier() -> String
}
func ==<T:Cacheable>(lhs: T, rhs: T) -> Bool {
return lhs.identifier() == rhs.identifier()
}
func !=<T:Cacheable>(lhs: T, rhs: T) -> Bool {
return lhs.identifier() != rhs.identifier()
}
func ==<T:Cacheable, U:Cacheable>(lhs: T, rhs: U) -> Bool {
return lhs.identifier() == rhs.identifier()
}
func !=<T:Cacheable, U:Cacheable>(lhs: T, rhs: U) -> Bool {
return lhs.identifier() != rhs.identifier()
}
ソリューション1の上記の制限を削除しました。これで、Dog
とCat
を簡単に比較できます。
==
関数のみを指定するだけでは十分ではない理由はわかりません。これはコンパイラーのバグかもしれません。とにかく、==
と!=
の両方の実装を提供する必要があります。Equatable
に準拠しない場合protocol Cacheable {
//....//
func identifier() -> String
}
func ==(lhs: Cacheable, rhs: Cacheable) -> Bool {
return lhs.identifier() == rhs.identifier()
}
func !=(lhs: Cacheable, rhs: Cacheable) -> Bool {
return lhs.identifier() != rhs.identifier()
}
ジェネリックを必要とせずに、Cacheable
をタイプとして使用できます。これにより、まったく新しい可能性が生まれます。例えば:
let c:[Cacheable] = [Dog(),RaceCar()]
c[0] == c[1]
c[0] != c[1]
ソリューション1および2では、このようなコードは失敗し、クラスでジェネリックを使用する必要があります。ただし、最新の実装ではCacheable
が型として扱われるため、[Cacheable]
型の配列を宣言できます。
Equatable
への適合を宣言しなくなったため、Equatable
パラメーターを受け入れる関数はCacheable
を受け入れません。明らかに、==
および!=
は別として、Cacheable
sに対して宣言しました。
これがコードの問題でない場合は、実際にこのソリューションをお勧めします。プロトコルをタイプとして扱うことができることは、多くの場合非常に便利です。
やってみて。
extension Equatable where Self : Cacheable {
}