Просто чтобы завершить вопрос об этом в Swift 5, вот демонстрация, которая будет работать в Swift 5, но не в Swift 4.2, учитывая ваш пример кода.
struct Val: ValueProtocol {}
struct VF: ValueFactory {
func create(with input: SomeInputImpl) -> Val {
return Val()
}
}
let child = Child<VF>()
child.input // SomeInputImpl
Но вы быпочти наверняка лучше использовать функции, а не GenericFactory
.Основная причина шаблона «Фабрика» заключается в работе с языками, в которых отсутствуют функции более высокого порядка и первоклассные типы, такими как Java до 8-й версии.В языках с функциями высшего порядка и первоклассными типами (такими как Swift) шаблон Factory обычно не нужен.Вы можете просто передать функцию (Input) -> Value
напрямую.
В вашем примере не показан вызывающий объект, поэтому трудно точно определить, какое решение на основе функций будет работать лучше, но в большинстве случаев универсальные функции являютсяГораздо лучший подход, чем протоколы + связанный тип + обобщение + наследование.В частности, смешивание наследования классов с ассоциированными типами приводит к неправильным углам (поскольку ассоциированные типы и наследование классов представляют собой несколько ортогональные подходы к полиморфизму).