Тип хранилища в переменной, используемой как тип позже

Я пытаюсь сохранить тип в переменной, чтобы позже использовать его, как тип 1-го класса.

class SomeModel {}

let someType = SomeModel.self
let array = Array<someType>()

В этом случае я мог бы сделать Array<SomeModel>() вместо этого, но я хочу обобщить его, и пусть подклассы предоставляют значение someType.

Однако я получаю ошибки, такие как someType isn't a type или use of undeclared type 'someType' в последней строке.

Ответ 1

func someFunc<T>(model: T) -> Array<T> {
    let array = Array<T>()
    return array
}

let someType = SomeModel.self
let array = someFunc(someType())

Похоже, это делает то, что я хочу. Единственным недостатком является то, что я должен создать экземпляр желаемого типа для передачи. В этом случае его минимальные накладные расходы, но это просто кажется пустой тратой.

Другое дело, что при использовании таких дженериков кажется, что генерируемые возможные типы вычисляются во время компиляции, поэтому во время выполнения model.dynamicType не обязательно соответствует T. В большинстве случаев это произойдет, но если вы делаете какие-либо действия, связанные с отражением, убедитесь, что вы действительно хорошо проверили свой вариант использования.

Ответ 2

В наши дни это может быть легче и гибко достигнуто с помощью .Type для класса или протокола. Обратите внимание, что доступны только функции, доступные этому корневому классу или протоколу, поэтому вы должны убедиться, что определен требуемый инициализатор определенного типа. Например:

protocol MyClass {
   init(someValue: Int)
}

class MyWrapper {

   let myClassType: MyClass.Type

   init(classType: MyClass.Type) {
      self.myClassType = classType
   }

   func new(with value: Int) -> MyClassType {
      return MyClassType.init(someValue: value)
   }

}

Теперь вы можете инициализировать этот довольно глупый класс factory с определенным классом, реализующим протокол MyClass, и когда вы вызываете функцию new() с целым значением, он генерирует новый экземпляр этого класса и возвращает его.