Создание коллекции без знания конкретного типа - PullRequest
0 голосов
/ 18 июня 2019

У меня есть класс, который является общим для типа T, который соответствует протоколу Collection.Теперь я хочу создать экземпляр коллекции, не зная конкретный тип коллекции, возможно ли это?

class FileStore<T: Collection>{

   var collection: T

   init(){
      collection = T() // This will never work
   }

}

1 Ответ

2 голосов
/ 18 июня 2019

Collection не имеет init среди требований к протоколу, поэтому вы не можете напрямую инициализировать экземпляр Collection. У вас есть несколько решений, хотя. Вы можете ограничить ограничение общего типа типом, который гарантирует наличие инициализации (например, Array), или вы можете создать свой собственный протокол, требующий init, заставить T требовать соответствия этому протоколу и расширить все Collection s, которые вы хотите хранить в соответствии с вашим протоколом.

Второй подход показан ниже:

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 и имеют пустые элементы, такие как Dictionary, Set и т. Д.).

class OtherFileStore<T: RangeReplaceableCollection> {
    var collection = T.init()
}
...