DeepDiff
DeepDiff copied to clipboard
Replace DiffAware to Hashable
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).
@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.
@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.
Can we improve API?
- in my case, I have
"id" : "28722789326579082360373574526566400"it's a string and I can't really use it withdiffId: Int. Plus I have - 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