<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Dec 17, 2015 at 2:17 PM, Etan Kissling via swift-users <span dir="ltr">&lt;<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



<div style="word-wrap:break-word">
I want to use instances of a custom class as Dictionary key.
<div>This requires the class to conform to Hashable.</div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="color:#bb2ca2">func</span> ==(lhs:
<span style="color:#4f8187">
KeyType1</span>, rhs: <span style="color:#4f8187">
KeyType1</span>) -&gt; <span style="color:#703daa">
Bool</span> { <span style="color:#bb2ca2">
return</span> lhs.<span style="color:#4f8187">id</span> == rhs.<span style="color:#4f8187">id</span> }</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">
<br>
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)">
<span style="color:#bb2ca2">final</span><span style="color:#000000">
</span><span style="color:#bb2ca2">class</span><span style="color:#000000"> KeyType1:
</span>Hashable<span style="color:#000000">,
</span>CustomStringConvertible<span style="color:#000000"> {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
let</span> id: <span style="color:#703daa">
String</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
init</span>(id: <span style="color:#703daa">
String</span>) { <span style="color:#bb2ca2">
self</span>.<span style="color:#4f8187">id</span> = id }</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
var</span> hashValue: <span style="color:#703daa">
Int</span> { <span style="color:#bb2ca2">
return</span> <span style="color:#4f8187">
id</span>.<span style="color:#703daa">hashValue</span> }</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
var</span> description: <span style="color:#703daa">
String</span> { <span style="color:#bb2ca2">
return</span> <span style="color:#4f8187">
id </span>}</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
}</div>
</div>
<div><br>
</div>
<div><br>
</div>
<div>Now I can use KeyType1 instances as key in Dictionary.</div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="color:#bb2ca2">var</span> collection1 = [<span style="color:#4f8187">KeyType1</span>(id:
<span style="color:#d12f1b">
&quot;foo&quot;</span>) : <span style="color:#703daa">
NSObject</span>()]</div>
</div>
<div><br>
</div>
<div><br>
</div>
<div>Testing works fine:</div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">let</span> key =
<span style="color:#4f8187">
collection1</span>.<span style="color:#703daa">first</span>!.<span style="color:#272ad8">0</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;        Key stored in collection:
<span style="color:#000000">
\</span>(<span style="color:#3d1d81">unsafeAddressOf</span><span style="color:#000000">(key)</span>) --
<span style="color:#000000">
\</span>(<span style="color:#000000">key</span>)&quot;<span style="color:#000000">)</span></div>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">
    <br>
</p>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
let</span> keyCopy = <span style="color:#4f8187">
KeyType1</span>(id: key.<span style="color:#4f8187">id</span>)</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;                        Key copy:
<span style="color:#000000">
\</span>(<span style="color:#3d1d81">unsafeAddressOf</span><span style="color:#000000">(keyCopy)</span>) --
<span style="color:#000000">
\</span>(<span style="color:#000000">keyCopy</span>)&quot;<span style="color:#000000">)</span></div>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">
    <br>
</p>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;                      Keys equal:
<span style="color:#000000">
\</span>(<span style="color:#000000">key
</span><span style="color:#31595d">==</span><span style="color:#000000"> keyCopy</span>)&quot;<span style="color:#000000">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;               Hash values equal:
<span style="color:#000000">
\</span>(<span style="color:#000000">key.</span><span style="color:#4f8187">hashValue</span><span style="color:#000000">
 == keyCopy.</span><span style="color:#4f8187">hashValue</span>)&quot;<span style="color:#000000">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;     Collection has item for key:
<span style="color:#000000">
\</span>(<span style="color:#4f8187">collection1</span><span style="color:#000000">[key] !=
</span><span style="color:#bb2ca2">nil</span>)&quot;<span style="color:#000000">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;Collection has item for key copy:
<span style="color:#000000">
\</span>(<span style="color:#4f8187">collection1</span><span style="color:#000000">[keyCopy] !=
</span><span style="color:#bb2ca2">nil</span>)&quot;<span style="color:#000000">)</span></div>
</div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>        Key stored in collection: 0x0000608000043d80 -- foo</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>                        Key copy: 0x00006080000440b0 -- foo</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>                      Keys equal: true</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>               Hash values equal: true</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>     Collection has item for key: true</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>Collection has item for key copy: true</b></div>
</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div>Next, I repeat the same set up -- but this time KeyType is a descendant of NSObject.</div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="color:#bb2ca2">func</span> ==(lhs:
<span style="color:#4f8187">
KeyType2</span>, rhs: <span style="color:#4f8187">
KeyType2</span>) -&gt; <span style="color:#703daa">
Bool</span> { <span style="color:#bb2ca2">
return</span> lhs.<span style="color:#4f8187">id</span> == rhs.<span style="color:#4f8187">id</span> }</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">
<br>
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">
<span style="color:#bb2ca2">final</span><span style="color:#000000">
</span><span style="color:#bb2ca2">class</span><span style="color:#000000"> KeyType2:
</span><span style="color:#703daa">NSObject</span><span style="color:#000000"> {
</span>// NSObject conforms to Hashable and CustomStringConvertible.</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
let</span> id: <span style="color:#703daa">
String</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
init</span>(id: <span style="color:#703daa">
String</span>) { <span style="color:#bb2ca2">
self</span>.<span style="color:#4f8187">id</span> = id;
<span style="color:#bb2ca2">
super</span>.<span style="color:#bb2ca2">init</span>() }</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
override</span> <span style="color:#bb2ca2">
var</span> hashValue: <span style="color:#703daa">
Int</span> { <span style="color:#bb2ca2">
return</span> <span style="color:#4f8187">
id</span>.<span style="color:#703daa">hashValue</span> }</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
override</span> <span style="color:#bb2ca2">
var</span> description: <span style="color:#703daa">
String</span> { <span style="color:#bb2ca2">
return</span> <span style="color:#4f8187">
id </span>}</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
}</div>
</div>
<div><br>
</div>
<div>Again, I create a Dictionary based on this key class.</div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="color:#bb2ca2">var</span> collection2 = [<span style="color:#4f8187">KeyType2</span>(id:
<span style="color:#d12f1b">
&quot;foo&quot;</span>) : <span style="color:#703daa">
NSObject</span>()]</div>
</div>
<div><br>
</div>
<div>Using the same tests, they fail now.</div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">let</span> key =
<span style="color:#4f8187">
collection2</span>.<span style="color:#703daa">first</span>!.<span style="color:#272ad8">0</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;        Key stored in collection:
<span style="color:#000000">
\</span>(<span style="color:#3d1d81">unsafeAddressOf</span><span style="color:#000000">(key)</span>) --
<span style="color:#000000">
\</span>(<span style="color:#000000">key</span>)&quot;<span style="color:#000000">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">
<br>
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
    <span style="color:#bb2ca2">
let</span> keyCopy = <span style="color:#4f8187">
KeyType2</span>(id: key.<span style="color:#4f8187">id</span>)</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;                        Key copy:
<span style="color:#000000">
\</span>(<span style="color:#3d1d81">unsafeAddressOf</span><span style="color:#000000">(keyCopy)</span>) --
<span style="color:#000000">
\</span>(<span style="color:#000000">keyCopy</span>)&quot;<span style="color:#000000">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">
<br>
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;                      Keys equal:
<span style="color:#000000">
\</span>(<span style="color:#000000">key
</span><span style="color:#31595d">==</span><span style="color:#000000"> keyCopy</span>)&quot;<span style="color:#000000">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;               Hash values equal:
<span style="color:#000000">
\</span>(<span style="color:#000000">key.</span><span style="color:#4f8187">hashValue</span><span style="color:#000000">
 == keyCopy.</span><span style="color:#4f8187">hashValue</span>)&quot;<span style="color:#000000">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;     Collection has item for key:
<span style="color:#000000">
\</span>(<span style="color:#4f8187">collection2</span><span style="color:#000000">[key] !=
</span><span style="color:#bb2ca2">nil</span>)&quot;<span style="color:#000000">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)">
<span style="color:#000000">   
</span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span>&quot;Collection has item for key copy:
<span style="color:#000000">
\</span>(<span style="color:#4f8187">collection2</span><span style="color:#000000">[keyCopy] !=
</span><span style="color:#bb2ca2">nil</span>)&quot;<span style="color:#000000">)</span></div>
</div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>        Key stored in collection: 0x0000608000044080 -- foo</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>                        Key copy: 0x00006080000440e0 -- foo</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>                      Keys equal: true</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>               Hash values equal: true</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>     Collection has item for key: true</b></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<b>Collection has item for key copy: false</b></div>
</div>
<div><br>
</div>
<div><br>
</div>
<div>What am I missing here?</div></div></blockquote><div><br></div><div>The == overload in the second case is not the one that gets put into the protocol witness table.  When you call == on two instances of your type, upcast to NSObject, the isEqual() method is called.</div><div><br></div><div>We are aware of this issue and it will be fixed when we move operators into types.</div><div><br></div><div>Dmitri</div></div><div><br></div>-- <br><div class="gmail_signature">main(i,j){for(i=2;;i++){for(j=2;j&lt;i;j++){if(!(i%j)){j=0;break;}}if<br>(j){printf(&quot;%d\n&quot;,i);}}} /*Dmitri Gribenko &lt;<a href="mailto:gribozavr@gmail.com" target="_blank">gribozavr@gmail.com</a>&gt;*/</div>
</div></div>