我有一个有趣的问题:
class ListCache {
public func getCachedList<T: Codable>() -> [T]? {
//loads list from file cache using Codable
}
}
让我说我有Foo课程:
class Foo: Codable {
var bar = ""
}
现在,我可以这样做:
let array: [Foo] = ListCache().getCachedList()
但我做不到这样的事情:
var listsToLoad: [AnyClass] = [Foo.self]
let clazz = listsToLoad[0]
let array: [Codable] = ListCache().getCachedList()
编译器给我一个错误:
无法明确专门化通用函数
这意味着我无法在循环中调用getCachedList()
因为我必须明确地给它一个类类型。
有没有办法实现这个目标?我也尝试过使用泛型类,但我几乎都是在同一点上结束。
编辑:
我尝试过创建:
class CodableClass: Codable {
}
然后:
class Foo: CodableClass {
//...
}
现在编译器说clazz未声明:
var listsToLoad: [CodableClass.Type] = [Foo.self]
for clazz in listsToLoad {
if let array: [clazz] = ListCache().getCachedList() {
print(array.count)
}
}
我也尝试了clazz.Type
和clazz.self
。
答案 0 :(得分:3)
我很确定为了调用泛型函数,必须在编译时知道该函数的参数类型。由于[Foo]
实际上只是Array<Foo>
的简写,因此也适用于类型化数组(尝试编写Array<clazz>
;它不会编译)。因此,当你在clazz
变量中有一个类型,这样实际的类只能在运行时知道,你不能用它来调用泛型函数,也不能声明一个类型的数组。
AFAIK,唯一的解决方案是:
使用[Codable]
或<:p>
找到另一种方法来做你想做的事: - (
由于我不知道你最终想要做什么,不幸的是,很难超越这一点。
答案 1 :(得分:0)
你可以试试
吗?class ListCache {
public func getCachedList<T: Cachable>() -> [T] {
return [(Foo() as! T)]
}
}
protocol Cachable: Codable { }
class CachableClass: Cachable {
class func test() -> String {
return "blo"
}
}
extension Cachable {
static func cachedValues() -> [Self] {
return cachedValuesTemplate(type: self)
}
private static func cachedValuesTemplate<T: Cachable>(type: T.Type) -> [T] {
return ListCache().getCachedList()
}
}
class Foo: CachableClass { }
var listsToLoad: [CachableClass.Type] = [Foo.self]
for clazz in listsToLoad {
print(clazz.cachedValues().count)
}