How to Properly Implement the Equatable Protocol in a Class Hierarchy

How to properly implement the Equatable protocol in a class hierarchy?

After lots of research and some trial and error I finally came up with a working solution. The first step was moving the == operator from inside the class to the global scope. This fixed the errors about static and final.

For the base class this became:

func == (lhs: Base, rhs: Base) -> Bool {
return lhs.x == rhs.x
}

class Base : Equatable {
var x : Int
}

And for the subclass:

func == (lhs: Subclass, rhs: Subclass) -> Bool {
return true
}

class Subclass : Base {
var y : String
}

Now the only part left is figuring out how to call the == operator of the base class from the == operator of the subclass. This led me to the final solution:

func == (lhs: Subclass, rhs: Subclass) -> Bool {
if lhs.y == rhs.y {
if lhs as Base == rhs as Base {
return true
}
}

return false
}

That first if statement results in a call to the == operator in the base class.


The final solution:

Base.swift:

func == (lhs: Base, rhs: Base) -> Bool {
return lhs.x == rhs.x
}

class Base : Equatable {
var x : Int
}

Subclass.swift:

func == (lhs: Subclass, rhs: Subclass) -> Bool {
if lhs.y == rhs.y {
if lhs as Base == rhs as Base {
return true
}
}

return false
}

class Subclass : Base {
var y : String
}

Implement Equatable for custom private class - Swift

You need to also declare your == operator function as private for this to work. Functions are by default scoped as internal, and you can't have an internal method with privately scoped parameters or return type.

private class Foo : Equatable {
var bar = ""
}

private func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.bar == rhs.bar
}

Swift Struct doesn't conform to protocol Equatable?

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 :)

Swift, how to implement Hashable protocol based on object reference?

If you are working with classes and not structs, you can use the ObjectIdentifier struct. Note that you also have to define == for your class in order to conform to Equatable (Hashable requires it). It would look something like this:

class MyClass: Hashable { }

func ==(lhs: MyClass, rhs: MyClass) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}

class MyClass: Hashable {
var hashValue: Int {
return ObjectIdentifier(self).hashValue
}
}


Related Topics



Leave a reply



Submit