У меня есть 3 структуры:
struct Address: Codable {
var addressLine1: String
}
struct Person: Codable {
var name: String
}
struct Order: Codable {
var person: Person?
var address: Address?
}
В моем классе ViewController я использую Mirror для доступа к каждому из свойств в Order:
let address = Address(addressLine1: "Some unknown address")
let person = Person(name: "Some unknown name")
let order = Order(person: person, address: address)
let newOrderMirror = Mirror(reflecting: order)
newOrderMirror.children.forEach {
display(child: $0.value)
}
В ViewController я реализовал 3 отображенияfunctions:
func display(child: Any) {
// this should never get called
print(child)
}
func display(child: Person) {
print(child)
}
func display(child: Address) {
print(child)
}
В приведенном выше случае он всегда вызывает func display(child: Any)
, однако я хочу, чтобы он вызывал функции с определенным параметром. Есть ли способ достичь этого без приведения типов? :
Конечно, это будет работать:
newOrderMirror.children.forEach {
if let bs = $0.value as? Person {
display(child: bs)
} else if let addr = $0.value as? Address {
display(child: addr)
}
display(child: $0.value)
}
Есть ли другой элегантный способ достичь желаемогоповедение без использования if-let + typecasting
?
Обновление 1:
Обнаружено что-то связанное здесь - Как вызвать более конкретный метод перегрузки
Обновление 2:
Я могу добиться более краткого решения, выполнив следующие действия:
- Объявить отображаемый протокол с помощью функции func display ()
- Пусть каждая модель реализует этот протокол
- Внутри forEach для каждого ребенка я могу просто привязать и типизировать протокол и вызвать метод отображения на нем
Однако это выглядит какуродливое решение для меня, так как модель сейчас выполняет 2 обязанности - я. Обработка / хранение данных, ii. Обработка, как данные отображаются. Вторая ответственность выглядит для меня более разумно для класса контроллера или презентатора, чем для реализации класса модели, поэтому я хочу избежать этого пути