I've been playing around with arrays of generic classes with different types. It's easiest to explain my problem with some sample code:
// Obviously a very pointless protocol...
protocol MyProtocol {
var value: Self { get }
}
extension Int : MyProtocol { var value: Int { return self } }
extension Double: MyProtocol { var value: Double { return self } }
class Container<T: MyProtocol> {
var values: [T]
init(_ values: T...) {
self.values = values
}
func myMethod() -> [T] {
return values
}
}
Now if I try to create an array of containers like so:
var containers: [Container<MyProtocol>] = []
I get the error:
Protocol 'MyProtocol' can only be used as a generic constraint because it has Self or associated type requirements.
To fix this I can use [AnyObject]
:
let containers: [AnyObject] = [Container<Int>(1, 2, 3), Container<Double>(1.0, 2.0, 3.0)]
// Explicitly stating the types just for clarity.
But now another 'problem' emerges when enumerating through containers
:
for container in containers {
if let c = container as? Container<Int> {
println(c.myMethod())
} else if let c = container as? Container<Double> {
println(c.myMethod())
}
}
As you can see in the code above, after determining the type of container
the same method is called in both cases. My question is:
Is there a better way to get the Container
with the correct type than casting to every possible type of Container
? Or is there something else I've overlooked?