我有一个类,它在符合收集协议的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,例如DictionarySet,等等)。
class OtherFileStore<T: RangeReplaceableCollection> {
    var collection = T.init()
}

10-07 13:18
查看更多