#ios #swift #generics
Вопрос:
Я пытаюсь создать простую фабрику объектов, используя перечисление. Регистр перечисления определяет тип объекта, который необходимо создать фабрике.
Я хотел бы иметь один метод, который получает перечисление и возвращает экземпляр. Задача здесь состоит в том, чтобы найти способ «привязать» регистр перечисления к типу объекта, который он должен создать.
Альтернативой является создание одного метода для каждого создаваемого класса, например: getMessenger()
. В этом случае мне вообще не понадобились бы перечисления. Но я хочу попробовать перечислить. Спасибо!
То, что я пробовал до сих пор:
class ModuleFactory {
enum Module {
case messenger
}
static func get<T>(module: Module) -> T {
switch module {
case .messenger: return Messenger(api: API(), configuration: Messenger.Configuration(enabledMenuOptions: [])) as! T
}
}
}
Комментарии:
1. Я не думаю, что здесь уместно использовать перечисления. Допустим , у меня есть еще один случай перечисления
anotherModule
, и у меня естьlet e = Bool.random() ? Module.messenger : .anotherModule
. Какой типget
вернется, если я это сделаюget(module: e)
? Компилятор не может сказать!2. Я бы просто сделал альтернативу, которую вы описали, — имел бы один метод для получения каждого типа вещей, если у вас нет действительно веской причины для этого, о которой я не знаю.
3. Спасибо @Sweeper. Я думаю, что вы правы, избегание перечисления позволит обеспечить большую гибкость, поскольку не будет однозначной связи между перечислением и производственными данными. В любом случае было бы неплохо знать, возможно ли иметь своего рода «связанный тип» для перечисления, зависящий от случая.
4. Нет; вы не можете связать связанные типы со значениями таким образом (поскольку случаи перечисления являются значениями, а не самими типами). Есть места, где это было бы полезно; однако этот пример на самом деле не относится к их числу. То, что вы создали здесь, может быть гораздо лучше реализовано как
shared
статический экземпляр или параметры по умолчанию. Фабрики очень редко бывают полезны в Swift. То, что вы ищете, вероятно, связано с функцией под названием «зависимые типы», где тип может зависеть от значения, но у Swift нет этой функции (и я ожидаю, что вы ее не получите; это довольно сложная функция).