swiftswift4.2equatable

Avoid Equatable and Hashable boilerplate, Swift 4.2


On project we are using classes for model's layer and because of that I have to write code like this:

// MARK: - Hashable
extension Player: Hashable {
    static func == (lhs: Player, rhs: Player) -> Bool {
        return lhs.hashValue == rhs.hashValue
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(self.name)
    }
}

Can this boilerplate can be somehow avoided? Is it possible to implement that Equatable compare by .hashValue by default? Thanks.


Solution

  • You could write your custom template via Stencil markup language and autogenerate the code using the Sourcery library.

    Or use the existing solutions (AutoEquatable, AutoHashable Sourcery templates).

    And also you could write something like this:

    protocol IHash: class { }
    
    extension IHash where Self: Hashable {
        static func ==(lhs: Self, rhs: Self) -> Bool {
            return lhs.hashValue == rhs.hashValue
        }
    }
    
    class User: IHash, Hashable {
        var name: String = ""
    
        func hash(into hasher: inout Hasher) {
            hasher.combine(self.name)
        }
    }
    

    It will help you to avoid duplication in different classes.