<div><div dir="auto">You are hardly alone struggling with this, it seems to come up every other week!</div><div dir="auto"><br></div><div dir="auto">You can write your own custom AnyProtocol type that includes Self, a pain but doable, e.g.:</div><div dir="auto"><br></div><div dir="auto"><div dir="auto">protocol A {</div><div dir="auto"> func a() -> String</div><div dir="auto">}</div><div dir="auto">protocol B {</div><div dir="auto"> func b() -> String</div><div dir="auto">}</div><div dir="auto">struct AB1: A, B, Hashable {</div><div dir="auto"> func a() -> String {</div><div dir="auto"> return "AB1.a"</div><div dir="auto"> }</div><div dir="auto"> func b() -> String {</div><div dir="auto"> return "AB1.b"</div><div dir="auto"> }</div><div dir="auto"> var hashValue: Int {</div><div dir="auto"> return 1</div><div dir="auto"> }</div><div dir="auto"> static func ==(lhs: AB1, rhs: AB1) -> Bool {</div><div dir="auto"> return true</div><div dir="auto"> }</div><div dir="auto">}</div><div dir="auto">struct AB2: A, B, Hashable {</div><div dir="auto"> func a() -> String {</div><div dir="auto"> return "AB2.a"</div><div dir="auto"> }</div><div dir="auto"> func b() -> String {</div><div dir="auto"> return "AB2.b"</div><div dir="auto"> }</div><div dir="auto"> var hashValue: Int {</div><div dir="auto"> return 2</div><div dir="auto"> }</div><div dir="auto"> static func ==(lhs: AB2, rhs: AB2) -> Bool {</div><div dir="auto"> return true</div><div dir="auto"> }</div><div dir="auto">}</div><div dir="auto">struct AnyABHashable: A, B, Hashable {</div><div dir="auto"> let equalsClosure: (_ rhs: AnyABHashable) -> Bool</div><div dir="auto"> let hashValueClosure: () -> Int</div><div dir="auto"> let bClosure: () -> String</div><div dir="auto"> let aClosure: () -> String</div><div dir="auto"> static func ==(lhs: AnyABHashable, rhs: AnyABHashable) -> Bool {</div><div dir="auto"> return lhs.equalsClosure(rhs)</div><div dir="auto"> }</div><div dir="auto"> var hashValue: Int {</div><div dir="auto"> return hashValueClosure()</div><div dir="auto"> }</div><div dir="auto"> func b() -> String {</div><div dir="auto"> return bClosure()</div><div dir="auto"> }</div><div dir="auto"> func a() -> String {</div><div dir="auto"> return aClosure()</div><div dir="auto"> }</div><div dir="auto">}</div><div dir="auto">// AB1 init</div><div dir="auto">extension AnyABHashable {</div><div dir="auto"> init(_ ab1: AB1) {</div><div dir="auto"> equalsClosure = { (r) in</div><div dir="auto"> if let rhs = r as? AB1 {</div><div dir="auto"> return ab1 == rhs</div><div dir="auto"> }</div><div dir="auto"> return false</div><div dir="auto"> }</div><div dir="auto"> hashValueClosure = { return ab1.hashValue }</div><div dir="auto"> aClosure = { return ab1.a() }</div><div dir="auto"> bClosure = { return ab1.b() }</div><div dir="auto"> }</div><div dir="auto">}</div><div dir="auto">// AB2 init</div><div dir="auto">extension AnyABHashable {</div><div dir="auto"> init(_ ab2: AB2) {</div><div dir="auto"> equalsClosure = { (r) in</div><div dir="auto"> if let rhs = r as? AB2 {</div><div dir="auto"> return ab2 == rhs</div><div dir="auto"> }</div><div dir="auto"> return false</div><div dir="auto"> }</div><div dir="auto"> hashValueClosure = { return ab2.hashValue }</div><div dir="auto"> aClosure = { return ab2.a() }</div><div dir="auto"> bClosure = { return ab2.b() }</div><div dir="auto"> }</div><div dir="auto">}</div><div dir="auto">let ab1Set = Set([AnyABHashable(AB1())])</div><div dir="auto">let ab2Set = Set([AnyABHashable(AB2())])</div><div dir="auto">let abSet = ab1Set.union(ab2Set)</div><div dir="auto">for ab in abSet {</div><div dir="auto"> ab.a()</div><div dir="auto"> ab.b()</div><div dir="auto">}</div><div dir="auto"><br></div></div><br><div class="gmail_quote"><div>On Tue, 11 Jul 2017 at 8:10 pm, Glen Huang via swift-users <<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I want to store some heterogeneous items all conform to a protocol inside a set, is it something possible to do in swift?<br>
<br>
I tried this example:<br>
<br>
```<br>
protocol Named: Hashable {<br>
var name: String { get }<br>
}<br>
<br>
extension Named {<br>
var hashValue: Int {<br>
return name.hashValue<br>
}<br>
<br>
static func ==(lhs: Self, rhs: Self) -> Bool {<br>
return <a href="http://lhs.name" rel="noreferrer" target="_blank">lhs.name</a> == <a href="http://rhs.name" rel="noreferrer" target="_blank">rhs.name</a><br>
}<br>
}<br>
<br>
struct Foo: Named {<br>
var name = "foo"<br>
}<br>
<br>
struct Bar: Named {<br>
var name = "bar"<br>
}<br>
<br>
var item = Set<Named>()<br>
item.insert(Foo())<br>
item.insert(Bar())<br>
```<br>
<br>
But it failed at `Set<Named>()` where it complained "Using 'Named' as a concrete type conforming to protocol 'Hashable' is not supported”.<br>
<br>
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?<br>
<br>
My use case is this:<br>
<br>
I have an object that can contain two sets of other objects:<br>
<br>
```<br>
class Parent {<br>
var foos: Set<Foo><br>
var bars: Set<Bar><br>
}<br>
```<br>
<br>
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?<br>
<br>
Thanks.<br>
_______________________________________________<br>
swift-users mailing list<br>
<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-users</a><br>
</blockquote></div></div><div dir="ltr">-- <br></div><div data-smartmail="gmail_signature">-- Howard.</div>