Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is difference between Any , Hashable , AnyHashable in Swift 3?

I scratch my head through lots of tutorials to understand the difference between the above 3 terms and find new term type erased container, now it becomes confusing to me. It raises lots of question.

Why does Swift introduce AnyHashable ?

What is the fundamental difference between these 3 terms?

Difference between Any and AnyHashable ?

Difference between Hashable and AnyHashable?

When to use Hashable and when to use AnyHashable ?

Last but most confusing, what is the meaning of type erased term in the context of AnyHashable ?

As a context, I followed Swift Evolution Proposal SE-0131.

like image 535
technerd Avatar asked Jun 13 '17 06:06

technerd


1 Answers

It's more important to understand what they are than what are the differences between them.

Any means "anything", ranging from swift enums, tuples, closures, structs, classes, protocols, whatever. Every type can be assigned to a variable of type Any.

Hashable is protocol that says "this object can be hashed i.e. has a hashcode". If your object can be hashed, implement this protocol, because lots of data structures (namely dictionaries and sets) need it.

So what is AnyHashable?

Normally, if you try to do this:

let a: Set<Hashable>?

it does not compile. This is because Hashable inherits from Equatable which contains Self.

Now, let's say you want to port a method from Objective-C to swift. That method takes a parameter of type NSSet. In Swift, this will turn into a Set, but what is its generic parameter? If we just put Any like we do with NSArrays, it does not work because Set's objects must be hashable. But if we put Set<Hashable> it does not work either because Hashable can only be used as a generic constraint. That's why they wrapped Hashable with an AnyHashable that does not use Self and so can be used as a generic parameter.

Regarding what "type erased" means:

Having Self in a protocol is kind of like a protocol with a generic parameter, and the generic parameter is always the conforming class. This causes the protocols to be unable to be used on its own like Set<Hashable> because the "generic parameter" is unknown. AnyHashable solves this problem by not using Self at all so it now becomes a normal struct. It "erases" the generic Self type.

like image 169
Sweeper Avatar answered Nov 16 '22 06:11

Sweeper