Как реализовать универсальную фабрику классов в Swift?
Я хочу "сделать" несколько экземпляров классов, похожих на базовый класс, но различающихся по базовому типу. (Совсем не то же самое, что типичные примеры фабрики классов "Animal" по всей сети!)
Приведенный ниже код близок к работе, но он требует, чтобы пользователь "выкинул" результат make, как в:
var f1 = FOO.make(version: FOO.Ver.f1) as! FOO1_32
Я не хочу, чтобы пользователь знал о конкретном типе класса, кроме FOO. Я видел другие предложения, и все они указывают, что решение состоит в том, чтобы определить марку с универсальным типом, который соответствует протоколу, как в:
make<T: FOOProtocol>(version: Ver = .f1) -> T
Однако это дает мне ошибку "универсальный параметр" T "не может быть выведен" при вызове FOO.make(версия: FOO.Ver.f1)
Кто-нибудь знает, как это сделать? Мой код детской площадки следующий.
protocol FOOProtocol
{
associatedtype FOOtype
var value: FOOtype {get set}
}
class FOO
{
enum Ver
{
case f1
case f2
}
class func make(version: Ver = .f1) -> FOO
{
print("FOO make")
switch version
{
case .f1:
return FOO1_32()
case .f2:
return FOO2_64()
}
}
}
class FOO1_32: FOO, FOOProtocol
{
typealias FOOtype = UInt32
private var fooVal: UInt32 = 0
var value: UInt32
{
get { return self.fooVal }
set { self.fooVal = newValue }
}
override init()
{
print("FOO1_32 init")
self.fooVal = 132
}
}
class FOO2_64: FOO, FOOProtocol
{
typealias FOOtype = UInt64
private var fooVal: UInt64 = 0
var value: UInt64
{
get { return self.fooVal }
set { self.fooVal = newValue }
}
override init()
{
print("FOO2_64 init")
self.fooVal = 264
}
}
var f1 = FOO.make(version: FOO.Ver.f1) // requires: as! FOO1_32
let f1v = f1.value
print("\(f1v)")
var f2 = FOO.make(version: FOO.Ver.f2) // requires: as! FOO2_64
let f2v = f2.value
print("\(f2v)")