Thanks for the detailed example. 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.
> On 12 Jul 2017, at 8:07 AM, Howard Lovatt <howard.lov...@gmail.com> wrote: > > 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 > <mailto: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 >> <mailto: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 <mailto: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 <http://lhs.name/> == rhs.name <http://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 <mailto:swift-users@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-users >>> <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