Hashable, Equatable and Measurement

So Swift documentation states that when a == b, then a.hashValue == b.hashValue (but the opposite is not necessarily true). However, is there ever a case where the first statement isn't true? To voice the argument, I have been considering Foundation.Measurement.

It is clear that:

import Foundation

let a = Measurement(value: 1.0, unit: UnitLength.meters)
let b = Measurement(value: 100.0, unit: UnitLength.centimeters)

a==b    // true

because obviously 100 cm is equal to 1 meter.

However, it is less clear to me that

a.hashValue == b.hashValue   // true.  This is TRUE

a.value // 1.0
b.value // 100.0

So this seems like a case where a and b should be equal but have different hash values because they have different units. I am running into this because I am finding Measurement completely useless in SwiftUI when equality holds and two different (but equal) values have different units.

Wanting to know people's thoughts. I am considering posting something in the Swift recommendations for changes but I don't know enough about this to be sure that this isn't an already discussed problem.

-Matt

That condition always needs to hold, or else the type wouldn’t work correctly in hashed collections such as dictionaries and sets. Those work on the assumption that equal values being compared (such as a dictionary keys or set members) will first have equal hashes, and then have equal values.

If you need (for example) 1 meter and 100 centimeters to be considered different for displaying as separate items in a list or something, then you can make a wrapper type that implements equality and hashing appropriately. But note this would require them to be considered not equal, and then it’s not obvious what the other comparison operations (greater-than and less-than) actually mean.

Hashable, Equatable and Measurement
 
 
Q