0

Consider this (simplified) program. I have a protocol Thing implemented in two structs, ThingOne and ThingTwo. I have a class ThingCollection that I would like to store arbitrary struct instances implementing the Thing protocol, meaning ThingOne() could be replaced with ThingTwo(). I have a class ThingCollectionCollection that I would like to store arbitrary instances of ThingCollection, regardless of its contained Thing instances:

protocol Thing: Equatable {

}

struct ThingOne: Thing {
    public static func ==(lhs: ThingOne, rhs: ThingOne) -> Bool {
        return true
    }
}

struct ThingTwo: Thing {
    public static func ==(lhs: ThingTwo, rhs: ThingTwo) -> Bool {
        return true
    }
}

class ThingCollection {
    public var things: [Thing] = [ThingOne()] // Error here
}

class ThingCollectionCollection {
    var thingCollections: [ThingCollection] = [ThingCollection()]
}

In a Swift Playground, I get an error at public var things: [Thing] stating

Protocol 'Thing' can only be used as a generic constraint because it has Self or associated type requirements.

This code works if protocol Thing inherits no other protocols, but in my case I do want implementations of Thing to be Equatable (and probably Hashable).

I suppose that I could make ThingCollection generic and use a different instance to store a single type of Thing, but then how could I store arbitrary ThingCollection instances in a ThingCollectionCollection? I am okay with an instance ThingCollection only being able to hold one type of Thing.

dgund
  • 3,459
  • 4
  • 39
  • 64
  • See also Rob Napier's blog post [about type erasers](http://robnapier.net/erasure). – jscs Aug 25 '16 at 20:49
  • The above blog post is really what helped me. The solution was using type erasers. – dgund Aug 25 '16 at 21:40
  • Although the bigger issue I have been facing is addressed in http://stackoverflow.com/questions/31762045/how-do-i-add-different-types-conforming-to-a-protocol-with-an-associated-type-to ... – dgund Aug 26 '16 at 03:25

0 Answers0