In this article we will explore what happens when we have different equatable methods for a type across packages and why this is a bad practise.
A. Multiple Equatable methods in same file:
Lets start with the following example:
1 2 3 4 5 6 7 8 9 10 11 |
import UIKit struct A: Equatable { var i: Int var j: Int } let lhs = A(i: 1, j: 2) let rhs = A(i: 2, j: 2) lhs == rhs |
As we expect lhs == rhs is false.
Lets remove now the Equatabl and add the == function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import UIKit func ==(lhs: A, rhs: A) -> Bool { lhs.j == rhs.j } struct A { var i: Int var j: Int } let lhs = A(i: 1, j: 2) let rhs = A(i: 2, j: 2) lhs == rhs |
As we expect the lhs == rhs is true.
Lets now add back the Equatable and observe what will happen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import UIKit func ==(lhs: A, rhs: A) -> Bool { lhs.j == rhs.j } struct A: Equatable { var i: Int var j: Int } let lhs = A(i: 1, j: 2) let rhs = A(i: 2, j: 2) lhs == rhs |
As we notice lhs == rhs is true, which means the == function takes priority.
B. Multiple Equatable methods across different packages
Lets now see what happens if we create a project and add a swift package (let’s call it MyLibrary).
Add the following code there:
1 2 3 4 5 6 7 8 9 |
public struct A: Equatable { var i: Int var j: Int public init(i: Int, j: Int) { self.i = i self.j = j } } |
On the main target let’s add now the following extension
1 2 3 4 5 |
extension A { static public func ==(lhs: A, rhs: A) -> Bool { lhs.j == rhs.j } } |
And lets a test in the main target:
1 2 3 |
let lhs = A(i: 1, j: 2) let rhs = A(i: 2, j: 2) XCTAssertEqual(lhs, rhs) |
The test fails. The priority goes to the default equatable method that created automatically on the “MyLibrary” module.