Я согласен с Константином в фундаментальной проблеме здесь. Этот код просто неверен, и Свифт говорит вам об этом. CustomAdapter.doSmth
не может принять произвольный ETableViewCell
, но adapter
утверждает, что должен.
Есть много решений, в зависимости от конкретной проблемы, которую вы пытаетесь решить. Вы указали, что хотите написать «лучший и более чистый код». Это говорит о том, что у вас есть существующий код, в котором вы обнаружите чрезмерное дублирование или приведение. Итак, что вы хотите сделать, это посмотреть на этот код и посмотреть, какой код дублируется, а затем мы можем помочь вам разработать общие решения, чтобы избежать этого дублирования. На этот вопрос нет универсального ответа; выбор абстракции, который вы делаете в одном направлении, сделает другие направления менее гибкими. Абстракция - это выбор; они должны быть сделаны в контексте.
Как правило, в Swift вы должны избегать использования подклассов. Есть некоторые, которые требуются из-за привязки к ObjC, но Swift-ориентированный код должен избегать подклассов. В вашем конкретном примере интересный класс имеет только одну функцию. Если это действительно так, то реализовать это легко. Используйте одну функцию:
func customAdapter(cell: PeopleTableViewCell) {}
class TestBaseController: UIViewController {
let adapter: (PeopleTableViewCell) -> Void = customAdapter
}
"Но моя настоящая проблема более сложна, чем эта!" Хорошо. Тогда мы должны поговорить о вашей настоящей проблеме. Абстрагирование этих вещей до самых простых форм должно привести к самым простым решениям. Если на самом деле все немного сложнее, вы можете использовать структуру и протокол.
protocol Adapter {
associatedtype Cell: UITableViewCell
func doSmth(cell: Cell)
}
struct CustomAdapter<Cell: ETableViewCell>: Adapter {
func doSmth(cell: Cell) {}
}
class TestBaseController: UIViewController {
let adapter: CustomAdapter<PeopleTableViewCell> = CustomAdapter()
}
Я замалчиваю вопрос о том, что может быть вашим вопросом, как заставить функцию, которая принимает только PeopleTableViewCell
, использоваться там, где требуется функция, которая принимает любой ETableViewCell
. Это невозможно. Это не ограничение в Swift; это просто по типу невозможно. Лучшее, что вы можете сделать, это добавить «ничего не делать» или «сбой», как объясняет Константин.
Если вы сможете немного подробнее определить, какую именно проблему в существующем коде вы пытаетесь исправить, мы, вероятно, поможем вам разработать более эффективные решения. Добавление дженериков не делает ваш код «лучше или чище» сам по себе (и, по моему опыту, большинству лучших решений вообще не нужны дженерики).