Я реализую шаблон посетителя в Swift 2.2 для рабочего проекта.
Чтобы мне не нужно было сокращать исходный код и сэкономить время, я буду использовать пример шаблона посетителей в swift от Октавиана Хойнацкого.
protocol PlanetVisitor {
func visit(planet: PlanetAlderaan)
func visit(planet: PlanetCoruscant)
func visit(planet: PlanetTatooine)
}
protocol Planet {
func accept(visitor: PlanetVisitor)
}
class PlanetAlderaan: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetCoruscant: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetTatooine: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class NameVisitor: PlanetVisitor {
var name = ""
func visit(planet: PlanetAlderaan) { name = "Alderaan" }
func visit(planet: PlanetCoruscant) { name = "Coruscant" }
func visit(planet: PlanetTatooine) { name = "Tatooine" }
}
Проблема, которую я пытаюсь решить, состоит в том, чтобы уменьшить шаблон для каждого класса, производного от Planet
. Как видите, все они имеют одну и ту же функцию, дублированную func accept(visitor: PlanetVisitor) { visitor.visit(self) }
.
Я попытался поместить реализацию по умолчанию в протокол Planet
и реализовать ее в базовом классе, и Swift, похоже, не разрешает это из-за разрешения перегрузки времени компиляции.
Примеры:
Реализация по умолчанию в протоколе:
extension Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
Базовый класс:
class PlanetBase: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetAlderaan: PlanetBase {}
class PlanetCoruscant: PlanetBase {}
class PlanetTatooine: PlanetBase {}
Кто-нибудь знает, как сделать функцию accept
универсальной и автоматически применять ее к каждому конкретному классу, производному от Planet
? Это не критическая проблема, но это отличная головоломка!