How come I can do this?
var dict = [AnyHashable : Int]()
dict[NSObject()] = 1
dict[""] = 2
This implies that NSObject
and String
are somehow a subtype of AnyHashable
but AnyHashable
is a struct
so, how do they allow this?
How come I can do this?
var dict = [AnyHashable : Int]()
dict[NSObject()] = 1
dict[""] = 2
This implies that NSObject
and String
are somehow a subtype of AnyHashable
but AnyHashable
is a struct
so, how do they allow this?
Consider that
Optional
is anenum
, which is also a value type – and yet you're freely able to convert aString
to anOptional<String>
. The answer is simply that the compiler implicitly performs these conversions for you.If we look at the SIL emitted for the following code:
We can see that the compiler inserts a call to
_swift_convertToAnyHashable
:Looking in AnyHashable.swift, we can see the function with the silgen name of
_swift_convertToAnyHashable
, which simply invokesAnyHashable
's initialiser.Therefore the above code is just equivalent to:
Although it's curious that the standard library also implements an extension for
Dictionary
(which @OOPer shows), allowing for a dictionary with aKey
of typeAnyHashable
to be subscripted by any_Hashable
conforming type (I don't believe there are any types that conform to_Hashable
, but notHashable
).The subscript itself should work fine without a special overload for
_Hashable
keys. Instead the default subscript (which would take anAnyHashable
key) could just be used with the above implicit conversion, as the following example shows:Edit: In Swift 4, both the aforementioned subscript overload and
_Hashable
have been removed from the stdlib by this commit with the description:Which confirms my suspicion.
You can find this code, when you cmd-click on
[
or]
ofdict[NSObject()] = 1
in the Swift editor of Xcode (8.2.1, a little different in 8.3 beta):_AnyHashableProtocol
and_Hashable
are hidden types, so you may need to check the Swift source code. Simply:_Hashable
is a hidden super-protocol ofHashable
, so,Int
,String
,NSObject
or all otherHashable
types conform to_Hashable
._AnyHashableProtocol
is a hidden protocol, whereAnyHashable
is the only type which conforms to_AnyHashableProtocol
.So, the extension above is very similar to this code in Swift 3.1.
You see, when you write such code like this:
You are using the
subscript
operator defined in the extension.