Reputation: 1723
I have a class which is generic over a type T which conforms to the Collection protocol. Now I want to instantiate the collection without knowing the concrete type of the collection, is this possible?
class FileStore<T: Collection>{
var collection: T
init(){
collection = T() // This will never work
}
}
Upvotes: 0
Views: 40
Reputation: 54735
Collection
doesn't have init
amongst its protocol requirements, so you cannot directly initialize a Collection
instance. You have several solutions though. You can either restrict your generic type constraint to a type that does guarantee having an init (such as Array
) or you can create your own protocol requiring init
, make T
require conformance to that protocol and extend all Collection
s that you want to be able to store to conform to your protocol.
The second approach is shown below:
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>>()
Or depending on which exact types you want to be able to store, using the built-in RangeReplaceableCollection
as your type constraint is even better. (Bear in mind that quite a few standard library types don't conform to RangeReplaceableCollection
that do conform to Collection
and have empty inits, such as Dictionary
, Set
, etc.).
class OtherFileStore<T: RangeReplaceableCollection> {
var collection = T.init()
}
Upvotes: 2