Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make struct Hashable?

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?

like image 222
MarksCode Avatar asked Feb 01 '17 05:02

MarksCode


People also ask

What does hashable mean Swift?

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.

What is hashable?

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.

What is Equatable and hashable in Swift?

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.

Is enum hashable?

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.)


2 Answers

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     } } 
like image 156
rmaddy Avatar answered Sep 22 '22 10:09

rmaddy


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) } 
like image 43
ChrisH Avatar answered Sep 23 '22 10:09

ChrisH