Я играл с массивами общих классов с разными типами. Проще всего объяснить мою проблему с помощью некоторого примера кода:
// 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
}
}
Теперь, если я попытаюсь создать массив контейнеров, например:
var containers: [Container<MyProtocol>] = []
Я получаю сообщение об ошибке:
Протокол "MyProtocol" может использоваться только в качестве общего ограничения, поскольку он имеет требования к себе или связанному типу.
Чтобы исправить это, я могу использовать [AnyObject]
:
let containers: [AnyObject] = [Container<Int>(1, 2, 3), Container<Double>(1.0, 2.0, 3.0)]
// Explicitly stating the types just for clarity.
Но теперь возникает другая "проблема" при перечислении через 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())
}
}
Как вы можете видеть в приведенном выше коде, после определения типа container
в обоих случаях вызывается тот же метод. Мой вопрос:
Есть ли лучший способ получить container
с правильным типом, чем приведение к любому возможному типу container
? Или есть что-то еще, что я забыл?