<div dir="ltr"><div class="gmail_default" style="font-family:georgia,serif">I believe if B inherits A, they are not the same type. So the rule doesn't apply here.</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Zhaoxin</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 2, 2016 at 7:02 AM, Nick Brook <span dir="ltr"><<a href="mailto:nrbrook@gmail.com" target="_blank">nrbrook@gmail.com</a>></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">Hi Jordan,<div><br></div><div>Thanks for the advice.</div><div><br></div><div>What if a subclass does implement hashValue differently? It seems you are saying a subclass should never override hashValue? Should Set not compare elements with == instead of hashValue?<br><div><br></div><div>
Thanks<br><span style="color:rgb(0,0,0);font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;display:inline!important;float:none">Nick</span><br style="color:rgb(0,0,0);font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br style="color:rgb(0,0,0);font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="color:rgb(0,0,0);font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;display:inline!important;float:none">M: <a href="tel:%2B44%20%280%297986%20048%20141" value="+447986048141" target="_blank">+44 (0)7986 048 141</a></span><div style="color:rgb(0,0,0);font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">W: <a href="http://nickbrook.me" target="_blank">http://nickbrook.me</a></div>
</div><div><div class="h5">
<br><div><blockquote type="cite"><div>On 1 Sep 2016, at 23:55, Jordan Rose <<a href="mailto:jordan_rose@apple.com" target="_blank">jordan_rose@apple.com</a>> wrote:</div><br><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><blockquote type="cite"><div><br>On Sep 1, 2016, at 15:44, Zhao Xin via swift-users <<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>> wrote:</div><br><div><div dir="ltr"><div class="gmail_default" style="font-family:georgia,serif">Hi Nick,</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Glad to help.</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">but when using third party classes I don’t know if the hash values are comparable<br></blockquote><div><br></div><div class="gmail_default" style="font-family:georgia,serif">You can create an extension with a convenient init(:), which creates a new instance of the super class basing on the instance of the sub class. That will guarantee the subtraction. Below code works in Xcode 7.3.1 with Swift 2.2.<br></div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default"><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">import</span><span><span> </span>Foundation</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">func</span><span><span> </span>==(lhs:<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>, rhs:<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>) -><span> </span></span><span style="color:rgb(112,61,170)">Bool</span><span><span> </span>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> <span> </span></span><span style="color:rgb(187,44,162)">return</span><span><span> </span>lhs.</span><span style="color:rgb(79,129,135)">id</span><span><span> </span>== rhs.</span><span style="color:rgb(79,129,135)">id</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>}</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(112,61,170)"><span style="color:rgb(187,44,162)">class</span><span><span> </span>Foo:</span><span>Hashable</span><span><span> </span>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> <span> </span></span><span style="color:rgb(187,44,162)">let</span><span><span> </span>id:</span><span style="color:rgb(112,61,170)">Int</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> <span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>hashValue:<span> </span></span><span style="color:rgb(112,61,170)">Int</span><span><span> </span>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> <span> </span></span><span style="color:rgb(187,44,162)">return</span><span><span> </span></span><span style="color:rgb(79,129,135)">id</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> }</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span> </span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> <span> </span></span><span style="color:rgb(187,44,162)">required</span><span><span> </span></span><span style="color:rgb(187,44,162)">init</span><span>(</span><span style="color:rgb(187,44,162)">_</span><span><span> </span>id:</span><span style="color:rgb(112,61,170)">Int</span><span>) {</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> <span> </span></span><span style="color:rgb(187,44,162)">self</span><span>.</span><span style="color:rgb(79,129,135)">id</span><span><span> </span>= id</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> }</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>}</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">class</span><span><span> </span>Bar:</span><span style="color:rgb(79,129,135)">Foo</span><span><span> </span>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> <span> </span></span><span style="color:rgb(187,44,162)">override</span><span><span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>hashValue:<span> </span></span><span style="color:rgb(112,61,170)">Int</span><span><span> </span><wbr>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> <span> </span></span><span style="color:rgb(187,44,162)">return</span><span><span> </span></span><span style="color:rgb(79,129,135)">id</span><span><span> </span>*<span> </span></span><span style="color:rgb(39,42,216)">5</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span> }</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>}</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">var</span><span><span> </span>fooSet:</span><span style="color:rgb(112,61,170)">Set</span><span><</span><span style="color:rgb(79,129,135)">Foo</span><span>> = [</span><span style="color:rgb(79,129,135)">Foo</span><span>(</span><span style="color:rgb(39,42,216)">10</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>(</span><span style="color:rgb(39,42,216)">9</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>(</span><span style="color:rgb(39,42,216)">8</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>(</span><span style="color:rgb(39,42,216)"><wbr>7</span><span>)]</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">var</span><span><span> </span>barSet:</span><span style="color:rgb(112,61,170)">Set</span><span><</span><span style="color:rgb(79,129,135)">Bar</span><span>> = [</span><span style="color:rgb(79,129,135)">Bar</span><span>(</span><span style="color:rgb(39,42,216)">8</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Bar</span><span>(</span><span style="color:rgb(39,42,216)">7</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Bar</span><span>(</span><span style="color:rgb(39,42,216)">6</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Bar</span><span>(</span><span style="color:rgb(39,42,216)">5</span><span><wbr>)]</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span>//fooSet.subtract(barSet) // error: cannot invoke 'subtract' with an argument list of type '(Set<Bar>)'</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(79,129,135)"><span>fooSet</span><span><span> </span>=<span> </span></span><span>fooSet</span><span>.</span><span style="color:rgb(61,29,129)">subtract</span><span>(</span><span>barSe<wbr>t</span><span><span> </span></span><span style="color:rgb(187,44,162)">as</span><span><span> </span></span><span style="color:rgb(112,61,170)">Set</span><span><</span><span>Foo</span><span>>) </span><span style="color:rgb(0,132,0);font-family:menlo">// works, but not what we want</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(79,129,135)">fooSet</span><span>.</span><span style="color:rgb(61,29,129)">forEach</span><span><span> </span>{<span> </span></span><span style="color:rgb(61,29,129)">print</span><span>(</span><span style="color:rgb(209,47,27)">"</span><span>\</span><span style="color:rgb(209,47,27)">(</span><span>$0.</span><span style="color:rgb(187,44,162)">d<wbr>ynamicType</span><span style="color:rgb(209,47,27)">), id:</span><span>\</span><span style="color:rgb(209,47,27)">(</span><span>$0.</span><span style="color:rgb(79,129,135)">id</span><span style="color:rgb(209,47,27)">)"</span><span>) }</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span>/*</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span> Foo, id:7</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span> Foo, id:10</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span> Foo, id:9</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span>*/</span></div></div></div></div></blockquote><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">This isn't really a sensible thing to do. The rules for Hashable require that `a == b` implies `a.hashValue == b.hashValue`, and `a.hashValue != b.hashValue` implies `a != b`. If you break these rules you're going to have problems no matter what static types you're using.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Upcasting from Set<Bar> to Set<Foo> is the most concise way to solve this problem.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Jordan</div></div></blockquote></div><br></div></div></div></div></blockquote></div><br></div>