Swift Struct doesn't conform to protocol Equatable?
Solution 1
OK, after lots of searching, it's working...
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
}
My Struct was in a class, so it didn't work.. I moved this Struct out of my class and now it's good :)
Solution 2
Swift 4.1 (and above) Updated answer:
Starting from Swift 4.1, all you have to is to conform to the Equatable
protocol without the need of implementing the ==
method. See: SE-0185 - Synthesizing Equatable and Hashable conformance.
Example:
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
Keep in mind that the default behavior for the ==
is to compare all the type properties (based on the example: lhs.id == rhs.id && lhs.value == rhs.value
). If you are aiming to achieve a custom behavior (comparing only one property for instance), you have to do it by yourself:
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
At this point, the equality would be based on the id
value, regardless of what's the value of value
.
Solution 3
The issue isn't that the struct is within a class. That is certainly allowable, and there are many instances where you might want to do that. The issue is in the implementation of the Equatable protocol. You have to give a global implementation of == (which you have done), but there is no entity MyStruct....it is ParentClass.MyStruct (if the struct is defined within a parent class). The example below in itself is probably not a good example in this case, but it does show how you can do this if needed.
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
Note: I like to implement Comparable rather than just Equatable, which will allow you to support sorting and other functionality.
Related videos on Youtube
Insou
Updated on October 12, 2020Comments
-
Insou over 3 years
How do I make a structure conform to protocol "Equatable"?
I'm using 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" } }
When I use "MyStruct", Xcode shows the error:
MyStruct does not conform to protocol "Equatable"
Do you have an idea to make MyStruct conform to protocol?
-
Cannoliopsida over 6 yearsSee DJohnson's answer: being in a class wasn't the issue
-
Aaron Frary over 5 yearsThis will be the right answer for most people who have this question going forward.
-
macky12345 about 4 yearshow to make as generic? so that I may use it in all of my class and struct