我有一个类,它在符合收集协议的T类型上是泛型的。现在我想在不知道集合的具体类型的情况下实例化集合,这可能吗?
class FileStore<T: Collection>{
var collection: T
init(){
collection = T() // This will never work
}
}
最佳答案
Collection
的协议要求中没有init
,因此无法直接初始化Collection
实例。不过,你有几种解决办法。您可以将泛型类型约束限制为保证具有init(如Array
)的类型,也可以创建自己的需要init
的协议,使T
需要与该协议一致,并扩展希望能够存储的所有Collection
以符合协议。
第二种方法如下所示:
protocol Initializable {
init()
}
class FileStore<T: Collection> where T: Initializable {
var collection: T
init(){
collection = T.init()
}
}
// Extend the `Collection` conformant types
extension Array: Initializable {}
extension Dictionary: Initializable {}
extension Set: Initializable {}
// Create a FileStore
FileStore<Array<Int>>()
FileStore<[String:Int]>()
FileStore<Set<String>>()
或者根据您希望能够存储的确切类型,使用内置的
RangeReplaceableCollection
作为类型约束甚至更好。(请记住,相当多的标准库类型不符合RangeReplaceableCollection
,它们确实符合Collection
,并且具有空的init,例如Dictionary
,Set
,等等)。class OtherFileStore<T: RangeReplaceableCollection> {
var collection = T.init()
}