Skip to content
This repository has been archived by the owner on Dec 5, 2022. It is now read-only.

Replace DiffAware to Hashable #36

Open
ton252 opened this issue Mar 16, 2019 · 3 comments
Open

Replace DiffAware to Hashable #36

ton252 opened this issue Mar 16, 2019 · 3 comments

Comments

@ton252
Copy link

ton252 commented Mar 16, 2019

Could you explain why we need to use DiffAware protocol when Hashable do the same thing and there is a lot of helper functional out-of-the-box like Hasher etc.

For example, we have a simple struct:

struct SomeStruct<T: DiffAware, U: DiffAware> {
  var value: T
  var valuesArray: [U]
}

And if we want to conform DiffAware protocol, we need to calculate diffId something like this:

 var diffId: Int {
    let valueIds = self.values.map({ $0.diffId })
    
    var hasher = Hasher()
    hasher.combine(self.value.diffId)
    hasher.combine(valueIds)
    
    return hasher.finalize()
}

And if all the objects conformed Hashable protocol, I will not need to use map in this case and it will affect the performance.

As I remember map complexity is O(n).

@onmyway133
Copy link
Owner

@ton252 Hi, Hashable and Equatable are in fact useful, but I've seen it has caused some confusions, so I introduced DiffAware with diffId and compare function to make things more explicit. And diffId would ensure more id uniquing.

@dlindenkreuz
Copy link
Contributor

@ton252 To avoid having to repeatedly conform types to DiffAware, you can do this:

extension DiffAware where Self: Hashable {
    public var diffId: Int {
        return hashValue
    }

    public static func compareContent(_ a: Self, _ b: Self) -> Bool {
        return a == b
    }
}

extension UUID: DiffAware {}
extension CGFloat: DiffAware {}
// ...

This way, you can conform any type that is already Hashable to DiffAware without implementing diffId and compareContent each time. Saved me a couple lines.

@dbof10
Copy link

dbof10 commented May 5, 2019

Can we improve API?

  1. in my case, I have
    "id" : "28722789326579082360373574526566400"
    it's a string and I can't really use it with diffId: Int. Plus I have
  2. I have
protocol BaseMessageViewModel: DiffAware  {

}
struct TextMessageViewModel: BaseMessageViewModel {
    
    public var diffId: Int {
        return hashValue
    }
   

I have a compile error
Protocol 'BaseMessageViewModel' can only be used as a generic constraint because it has Self or associated type requirements

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants