I don't think you can do that in an ideal way yet. I saw there was some talk about "opening existentials" here, but if you're a Swift beginner you probably don't want to read that. It makes me dizzy and I've been using Swift for a while.
If you really need a list of Cats with different type params, one possibility is to create a "type erased" version of a Cat...
struct AnyCat {
let cat: Any
let eatFood: () -> Void
let eat: (Any) -> Void
let getFood() -> Any
init<T>(_ cat: Cat<T>) {
self.cat = cat
self.eatFood = { cat.eat(cat.food) }
self.eat = { anyFood in cat.eat(anyFood as! T) }
self.getFood = { cat.food }
}
var food: Any { getFood() }
}
var cats = [AnyCat(Cat<Int>()), AnyCat(Cat<String>())]
for cat in cats {
cat.eatFood()
}
Disclaimer: I did not put that in Xcode. There may be typos or mistakes, but I hope it shows the idea. In the init
of the AnyWhatever
, you can create closures that know about T, cast from Any to T, etc., in order to create properties and methods of the AnyCat
as needed.