onmyway133 / DeepDiff

🦀Amazingly incredible extraordinary lightning fast diffing in Swift
https://onmyway133.com/apps/
Other
2.05k stars 145 forks source link

Replace DiffAware to Hashable #36

Open ton252 opened 5 years ago

ton252 commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

@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 commented 5 years ago

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```