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.:
protocol A { func a() -> String } protocol B { func b() -> String } struct AB1: A, B, Hashable { func a() -> String { return "AB1.a" } func b() -> String { return "AB1.b" } var hashValue: Int { return 1 } static func ==(lhs: AB1, rhs: AB1) -> Bool { return true } } struct AB2: A, B, Hashable { func a() -> String { return "AB2.a" } func b() -> String { return "AB2.b" } var hashValue: Int { return 2 } static func ==(lhs: AB2, rhs: AB2) -> Bool { return true } } enum AB1Or2: A, B, Hashable { case ab1(AB1) case ab2(AB2) func a() -> String { switch self { case .ab1(let ab1Arg): return ab1Arg.a() case .ab2(let ab2Arg): return ab2Arg.a() } } func b() -> String { switch self { case .ab1(let ab1Arg): return ab1Arg.b() case .ab2(let ab2Arg): return ab2Arg.b() } } var hashValue: Int { switch self { case .ab1(let ab1Arg): return ab1Arg.hashValue case .ab2(let ab2Arg): return ab2Arg.hashValue } } static func ==(lhs: AB1Or2, rhs: AB1Or2) -> Bool { switch lhs { case .ab1(let lhsAB1): switch rhs { case .ab1(let rhsAB1): return lhsAB1 == rhsAB1 default: return false } case .ab2(let lhsAB2): switch rhs { case .ab2(let rhsAB2): return lhsAB2 == rhsAB2 default: return false } } } } let ab1s = Set([AB1Or2.ab1(AB1())]) let ab2s = Set([AB1Or2.ab2(AB2())]) let abs = ab1s.union(ab2s) On Tue, 11 Jul 2017 at 10:46 pm, Glen Huang <hey...@gmail.com> wrote: > Thanks for bringing AnyHashable to my attention. > > 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? > > On 11 Jul 2017, at 7:38 PM, Howard Lovatt <howard.lov...@gmail.com> wrote: > > You can have a set of AnyHashable: > > var item = Set<AnyHashable>() > item.insert(AnyHashable(Foo())) > item.insert(AnyHashable(Bar())) > > > Depends what you will do with the set if this is viable or not. You can > also use classes and ObjectID. > > You might want this though: > > var item = [AnyHashable: Any] > > extension Dictionary where Key == AnyHashable, Value: Hashable { > func insert(_ value: Value) { > self[AnyHashable(value)] == value > } > } > > item.insert(Foo()) > item.insert(Bar()) > > > So you get at the stored value. > > -- Howard. > > On 11 Jul 2017, at 8:09 pm, Glen Huang via swift-users < > swift-users@swift.org> wrote: > > Hi, > > I want to store some heterogeneous items all conform to a protocol inside > a set, is it something possible to do in swift? > > I tried this example: > > ``` > protocol Named: Hashable { > var name: String { get } > } > > extension Named { > var hashValue: Int { > return name.hashValue > } > > static func ==(lhs: Self, rhs: Self) -> Bool { > return lhs.name == rhs.name > } > } > > struct Foo: Named { > var name = "foo" > } > > struct Bar: Named { > var name = "bar" > } > > var item = Set<Named>() > item.insert(Foo()) > item.insert(Bar()) > ``` > > But it failed at `Set<Named>()` where it complained "Using 'Named' as a > concrete type conforming to protocol 'Hashable' is not supported”. > > 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? > > My use case is this: > > I have an object that can contain two sets of other objects: > > ``` > class Parent { > var foos: Set<Foo> > var bars: Set<Bar> > } > ``` > > 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? > > Thanks. > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users > > > -- -- Howard.
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users