構造をプロトコル「Equatable」に準拠させるにはどうすればよいですか?
Xcode 7.3.1を使用しています
struct MyStruct {
var id: Int
var value: String
init(id: Int, value: String) {
self.id = id
self.value = value
}
var description: String {
return "blablabla"
}
}
「MyStruct」を使用すると、Xcodeに次のエラーが表示されます。
MyStructはプロトコル「Equatable」に準拠していません
MyStructをプロトコルに準拠させるアイデアはありますか?
OK、たくさんの検索の後、それは働いています...
struct MyStruct {
var id: Int
var value: String
init(id: Int, value: String) {
self.id = id
self.value = value
}
var description: String {
return "blablabla"
}
}
extension MyStruct: Equatable {}
func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
let areEqual = lhs.id == rhs.id &&
lhs.value == rhs.value
return areEqual
}
私のStructはクラスに属していたので、うまくいきませんでした。このStructをクラスから移動しました。
Swift 4.1)から開始する必要があるのは、==
メソッドを実装せずに Equatable
プロトコルに準拠することだけです。参照: SE-0185-等化可能およびハッシュ可能適合性の合成 。
例:
struct MyStruct: Equatable {
var id: Int
var value: String
}
let obj1 = MyStruct(id: 101, value: "object")
let obj2 = MyStruct(id: 101, value: "object")
obj1 == obj2 // true
心に留めておく==
のデフォルトの動作は、タイププロパティを比較することですall例に基づいて:lhs.id == rhs.id && lhs.value == rhs.value
)。カスタムの動作を実現しようとしている場合(たとえば、1つのプロパティのみを比較する場合)、自分でそれを行う必要があります。
struct MyStruct: Equatable {
var id: Int
var value: String
}
extension MyStruct {
static func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
return lhs.id == rhs.id
}
}
let obj1 = MyStruct(id: 101, value: "obj1")
let obj2 = MyStruct(id: 101, value: "obj2")
obj1 == obj2 // true
この時点で、id
の値が何であるかに関係なく、等式はvalue
の値に基づきます。
問題は、構造体がクラス内にあるということではありません。それは確かに許容され、あなたがそれをしたいかもしれない多くの例があります。問題は、Equatableプロトコルの実装にあります。 ==(実行済み)のグローバル実装を指定する必要がありますが、MyStruct ....というエンティティはありません(ParentClass.MyStructです(構造体が親クラス内で定義されている場合)。以下の例自体はおそらくこの場合の良い例ではありませんが、必要に応じてこれを行う方法を示しています。
class ParentClass {
struct MyStruct {
var id: Int
var value: String
init(id: Int, value: String) {
self.id = id
self.value = value
}
var description: String {
return "blablabla"
}
}
}
extension ParentClass.MyStruct: Equatable {}
func ==(lhs: ParentClass.MyStruct, rhs: ParentClass.MyStruct) -> Bool {
let areEqual = lhs.id == rhs.id &&
lhs.value == rhs.value
return areEqual
}
let s1 = ParentClass.MyStruct(id: 1, value: "one")
let s2 = ParentClass.MyStruct(id: 2, value: "two")
let s3 = ParentClass.MyStruct(id: 1, value: "one")
s1.description //blablabla
s1 == s2 //false
s3 == s1 //true
注:並べ替えやその他の機能をサポートできるようにするため、EquatableだけでなくComparableを実装するのが好きです。