I'm trying to create a dictionary of the sort [petInfo : UIImage]()
but I'm getting the error Type 'petInfo' does not conform to protocol 'Hashable'
. My petInfo struct is this:
struct petInfo { var petName: String var dbName: String }
So I want to somehow make it hashable but none of its components are an integer which is what the var hashValue: Int
requires. How can I make it conform to the protocol if none of its fields are integers? Can I use the dbName
if I know it's going to be unique for all occurrences of this struct?
In Swift, a Hashable is a protocol that provides a hashValue to our object. The hashValue is used to compare two instances. To use the hashValue , we first have to conform (associate) the type (struct, class, etc) to Hashable property.
An object is said to be hashable if it has a hash value that remains the same during its lifetime. It has a __hash__() method and it can be compared to other objects. For this, it needs the __eq__() or __cmp__()method. If hashable objects are equal when compared, then they have same hash value.
Equatable is also the base protocol for the Hashable and Comparable protocols, which allow more uses of your custom type, such as constructing sets or sorting the elements of a collection. struct Person { var name: String var age: String } 1.
For a struct , all its stored properties must conform to Hashable . For an enum , all its associated values must conform to Hashable . (An enum without associated values has Hashable conformance even without the declaration.)
Simply return dbName.hashValue
from your hashValue
function. FYI - the hash value does not need to be unique. The requirement is that two objects that equate equal must also have the same hash value.
struct PetInfo: Hashable { var petName: String var dbName: String var hashValue: Int { return dbName.hashValue } static func == (lhs: PetInfo, rhs: PetInfo) -> Bool { return lhs.dbName == rhs.dbName && lhs.petName == rhs.petName } }
As of Swift 5 var hashValue:Int
has been deprecated in favour of func hash(into hasher: inout Hasher)
(introduced in Swift 4.2), so to update the answer @rmaddy gave use:
func hash(into hasher: inout Hasher) { hasher.combine(dbName) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With