[swift-users] =?utf-8?Q?=E2=81=A8Is_?=it possible to store a set of heterogeneous items with protocol?

Adrian Zubarev adrian.zubarev at devandartist.com
Tue Jul 11 08:29:31 CDT 2017


No it does not have to be a generic enum at all, as long you do not want extending the types from a diffrent module. Simply add a new enum case for each type you need, like `case string(String)`. You may also want to ask the wrapped type for it's hashValue so that it will hash correctly.

--  
Adrian Zubarev
Sent with Airmail  

Am 11. Juli 2017 um 15:15:11, Glen Huang (heyhgl at gmail.com(mailto:heyhgl at gmail.com)) schrieb:

>  
> NM, I think you meant this?  
>  
> enum Either<T1, T2> {  
> case Left(T1)  
> case Right(T2)
> }
>  
> > On 11 Jul 2017, at 9:06 PM, Glen Huang via swift-users <swift-users at swift.org(mailto:swift-users at swift.org)> wrote:  
> > This sounds pretty interesting.  
> >  
> > But I can’t totally wrap my head around it. How do I "wrap types into enum cases”? Could you provide a sample code? Thanks.  
> >  
> > > On 11 Jul 2017, at 8:50 PM, Adrian Zubarev <adrian.zubarev at devandartist.com(mailto:adrian.zubarev at devandartist.com)> wrote:  
> > > If the solution you seek is not designed so that the module user can extend the set of types then you could wrap your types into enum cases and use the enum for your set. ;) When Swift will support anonymous enum cases, this will be an elegant solution to these type of things.  
> > >  
> > > --  
> > > Adrian Zubarev
> > > Sent with Airmail  
> > >  
> > > Am 11. Juli 2017 um 14:46:12, Glen Huang via swift-users (swift-users at swift.org(mailto:swift-users at swift.org)) schrieb:
> > >  
> > > >  
> > > > 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.lovatt at gmail.com(mailto:howard.lovatt at 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 at swift.org(mailto:swift-users at 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 at swift.org(mailto:swift-users at swift.org)
> > > > > > https://lists.swift.org/mailman/listinfo/swift-users
> > > >  
> > > > _______________________________________________
> > > > swift-users mailing list
> > > > swift-users at swift.org(mailto:swift-users at swift.org)
> > > > https://lists.swift.org/mailman/listinfo/swift-users
> >  
> > _______________________________________________
> > swift-users mailing list
> > swift-users at swift.org(mailto:swift-users at swift.org)
> > https://lists.swift.org/mailman/listinfo/swift-users
>  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170711/a31b6777/attachment.html>


More information about the swift-users mailing list