<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Thanks for the detailed example.<div class=""><br class=""></div><div class="">It makes sense. But the code can grow pretty quickly with just a few methods and a few concrete types. Also most are repetitive. I’ll try to incorporate this pattern when the use case is simple. But for more complex ones I guess I have to stick with classes for now.</div><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 12 Jul 2017, at 8:07 AM, Howard Lovatt &lt;<a href="mailto:howard.lovatt@gmail.com" class="">howard.lovatt@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><div dir="auto" class="">I would be tempted to use classes for this if you can use single inheritance. If you need multiple inheritance then use an enum and hand code the dispatch, a lot more work :(. E.G.:</div><div dir="auto" class=""><br class=""></div><div dir="auto" class=""><div dir="auto" class="">protocol A {</div><div dir="auto" class="">&nbsp; &nbsp; func a() -&gt; String</div><div dir="auto" class="">}</div><div dir="auto" class="">protocol B {</div><div dir="auto" class="">&nbsp; &nbsp; func b() -&gt; String</div><div dir="auto" class="">}</div><div dir="auto" class="">struct AB1: A, B, Hashable {</div><div dir="auto" class="">&nbsp; &nbsp; func a() -&gt; String {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; return "AB1.a"</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; func b() -&gt; String {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; return "AB1.b"</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; var hashValue: Int {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; return 1</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; static func ==(lhs: AB1, rhs: AB1) -&gt; Bool {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; return true</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">}</div><div dir="auto" class="">struct AB2: A, B, Hashable {</div><div dir="auto" class="">&nbsp; &nbsp; func a() -&gt; String {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; return "AB2.a"</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; func b() -&gt; String {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; return "AB2.b"</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; var hashValue: Int {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; return 2</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; static func ==(lhs: AB2, rhs: AB2) -&gt; Bool {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; return true</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">}</div><div dir="auto" class="">enum AB1Or2: A, B, Hashable {</div><div dir="auto" class="">&nbsp; &nbsp; case ab1(AB1)</div><div dir="auto" class="">&nbsp; &nbsp; case ab2(AB2)</div><div dir="auto" class="">&nbsp; &nbsp; func a() -&gt; String {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; switch self {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; case .ab1(let ab1Arg):&nbsp;</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ab1Arg.a()</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; case .ab2(let ab2Arg):&nbsp;</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ab2Arg.a()</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; func b() -&gt; String {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; switch self {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; case .ab1(let ab1Arg):&nbsp;</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ab1Arg.b()</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; case .ab2(let ab2Arg):&nbsp;</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ab2Arg.b()</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; var hashValue: Int {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; switch self {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; case .ab1(let ab1Arg):&nbsp;</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ab1Arg.hashValue</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; case .ab2(let ab2Arg):&nbsp;</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ab2Arg.hashValue</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; static func ==(lhs: AB1Or2, rhs: AB1Or2) -&gt; Bool {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; switch lhs {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; case .ab1(let lhsAB1):</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch rhs {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case .ab1(let rhsAB1):&nbsp;</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return lhsAB1 == rhsAB1</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; case .ab2(let lhsAB2):</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch rhs {</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case .ab2(let rhsAB2):&nbsp;</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return lhsAB2 == rhsAB2</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div dir="auto" class="">&nbsp; &nbsp; }</div><div dir="auto" class="">}</div><div dir="auto" class="">let ab1s = Set([AB1Or2.ab1(AB1())])</div><div dir="auto" class="">let ab2s = Set([AB1Or2.ab2(AB2())])</div><div dir="auto" class="">let abs = ab1s.union(ab2s)</div><div dir="auto" class=""><br class=""></div></div><br class=""><div class="gmail_quote"><div class="">On Tue, 11 Jul 2017 at 10:46 pm, Glen Huang &lt;<a href="mailto:heyhgl@gmail.com" class="">heyhgl@gmail.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space" class="">Thanks for bringing&nbsp;AnyHashable to my attention.<div class=""><br class=""></div><div class="">It works, but the types are now erased. I want to have a union of the two sets because I want to loop over it to treat each contained item as Named, so I can process them as though they are of the same type. Is this type of use case really should be addressed using super class?</div></div><div style="word-wrap:break-word;line-break:after-white-space" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On 11 Jul 2017, at 7:38 PM, Howard Lovatt &lt;<a href="mailto:howard.lovatt@gmail.com" target="_blank" class="">howard.lovatt@gmail.com</a>&gt; wrote:</div><br class="m_-4307674380725028104Apple-interchange-newline"><div class=""><div dir="auto" class="">You can have a set of AnyHashable:<div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><font class=""><span style="background-color:rgba(255,255,255,0)" class="">var item = Set&lt;AnyHashable&gt;()<br class="">item.insert(AnyHashable(Foo()))<br class="">item.insert(AnyHashable(Bar()))</span></font></blockquote><div class=""><br class=""></div>Depends what you will do with the set if this is viable or not. You can also use classes and ObjectID.</div><div class=""><br class=""></div><div class="">You might want this though:</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><font class=""><span style="background-color:rgba(255,255,255,0)" class="">var item = [AnyHashable: Any]<br class=""></span></font></blockquote>extension Dictionary where Key == AnyHashable, Value: Hashable {</div><div class="">&nbsp; &nbsp; func insert(_ value: Value) {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; self[AnyHashable(value)] == value</div><div class="">&nbsp; &nbsp; }</div><div class="">}<br class=""><blockquote type="cite" class=""><font class=""><span style="background-color:rgba(255,255,255,0)" class="">item.insert(Foo())<br class="">item.insert(Bar())</span></font></blockquote><div class=""><br class=""></div>So you get at the stored value.<br class=""><br class=""><div class="">-- Howard.</div><div class=""><br class="">On 11 Jul 2017, at 8:09 pm, Glen Huang via swift-users &lt;<a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><span class="">Hi, </span><br class=""><span class=""></span><br class=""><span class="">I want to store some heterogeneous items all conform to a protocol inside a set, is it something possible to do in swift?</span><br class=""><span class=""></span><br class=""><span class="">I tried this example:</span><br class=""><span class=""></span><br class=""><span class="">```</span><br class=""><span class="">protocol Named: Hashable {</span><br class=""><span class=""> &nbsp;&nbsp;var name: String { get }</span><br class=""><span class="">}</span><br class=""><span class=""></span><br class=""><span class="">extension Named {</span><br class=""><span class=""> &nbsp;&nbsp;var hashValue: Int {</span><br class=""><span class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return name.hashValue</span><br class=""><span class=""> &nbsp;&nbsp;}</span><br class=""><span class=""></span><br class=""><span class=""> &nbsp;&nbsp;static func ==(lhs: Self, rhs: Self) -&gt; Bool {</span><br class=""><span class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return <a href="http://lhs.name/" target="_blank" class="">lhs.name</a> == <a href="http://rhs.name/" target="_blank" class="">rhs.name</a></span><br class=""><span class=""> &nbsp;&nbsp;}</span><br class=""><span class="">}</span><br class=""><span class=""></span><br class=""><span class="">struct Foo: Named {</span><br class=""><span class=""> &nbsp;&nbsp;var name = "foo"</span><br class=""><span class="">}</span><br class=""><span class=""></span><br class=""><span class="">struct Bar: Named {</span><br class=""><span class=""> &nbsp;&nbsp;var name = "bar"</span><br class=""><span class="">}</span><br class=""><span class=""></span><br class=""><span class="">var item = Set&lt;Named&gt;()</span><br class=""><span class="">item.insert(Foo())</span><br class=""><span class="">item.insert(Bar())</span><br class=""><span class="">```</span><br class=""><span class=""></span><br class=""><span class="">But it failed at `Set&lt;Named&gt;()` where it complained "Using 'Named' as a concrete type conforming to protocol 'Hashable' is not supported”.</span><br class=""><span class=""></span><br class=""><span class="">After watching the WWDC session "Protocol-Oriented Programming in Swift” by Dave Abrahams, I try to use protocols whenever possible. But I can’t seem to overcome this barrier. Set.Element must confirm to Hashable, which inherits from Equatable, which has self requirement, which ultimately means that Set.Element all must be of the same type. So it seems it’s impossible to have heterogeneous items using protocol. Is that the case?</span><br class=""><span class=""></span><br class=""><span class="">My use case is this:</span><br class=""><span class=""></span><br class=""><span class="">I have an object that can contain two sets of other objects:</span><br class=""><span class=""></span><br class=""><span class="">```</span><br class=""><span class="">class Parent {</span><br class=""><span class=""> &nbsp;&nbsp;var foos: Set&lt;Foo&gt;</span><br class=""><span class=""> &nbsp;&nbsp;var bars: Set&lt;Bar&gt;</span><br class=""><span class="">}</span><br class=""><span class="">```</span><br class=""><span class=""></span><br class=""><span class="">I want to define a computed property “all” that is the union of the two sets. Foo and Bar conform to the same protocol. I wonder what return type I should use for the union? Do I have to go back to OOP and define a super class for Foo and Bar?</span><br class=""><span class=""></span><br class=""><span class="">Thanks.</span><br class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-users mailing list</span><br class=""><span class=""><a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-users</a></span><br class=""></div></blockquote></div></div></div></blockquote></div><br class=""></div></div></blockquote></div></div><div dir="ltr" class="">-- <br class=""></div><div data-smartmail="gmail_signature" class="">-- Howard.</div>
</div></blockquote></div><br class=""></div></body></html>