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.