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.
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 NSArray
s, 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.
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