Я пытаюсь понять, почему, когда раздел общего метода игнорируетсяНеправильная Обобщенная функция перегрузки называется
Я сделал простой случай использования в Swift 3 (вы можете скопировать код в игровой площадке, если вы хочу поиграть с ним):
//MARK: - Classes
protocol HasChildren {
var children:[Human] {get}
}
class Human {}
class SeniorHuman : Human, HasChildren {
var children: [Human] {
return [AdultHuman(), AdultHuman()]
}
}
class AdultHuman : Human, HasChildren {
var children: [Human] {
return [YoungHuman(), YoungHuman(), YoungHuman()]
}
}
class YoungHuman : Human {}
//MARK: - Generic Methods
/// This method should only be called for YoungHuman
func sayHelloToFamily<T: Human>(of human:T) {
print("Hello \(human). You have no children. But do you conform to protocol? \(human is HasChildren)")
}
/// This method should be called for SeniorHuman and AdultHuman, but not for YoungHuman...
func sayHelloToFamily<T: Human>(of human:T) where T: HasChildren {
print("Hello \(human). You have \(human.children.count) children, good for you!")
}
Хорошо, давайте теперь проведем несколько тестов. Если мы имеем:
let senior = SeniorHuman()
let adult = AdultHuman()
print("Test #1")
sayHelloToFamily(of: senior)
print("Test #2")
sayHelloToFamily(of: adult)
if let seniorFirstChildren = senior.children.first {
print("Test #3")
sayHelloToFamily(of: seniorFirstChildren)
print("Test #4")
sayHelloToFamily(of: seniorFirstChildren as! AdultHuman)
}
Выход:
Test #1
Hello SeniorHuman. You have 2 children, good for you!
Test #2
Hello AdultHuman. You have 3 children, good for you!
Test #3
Hello AdultHuman. You have no children. But do you conform to protocol? true
//Well, why are you not calling the other method then?
Test #4
Hello AdultHuman. You have 3 children, good for you!
//Oh... it's working here... It seems that I just can't use supertyping
... Ну, по-видимому, для ОГОВОРКА where
протокол для работы, нам необходимо пройти сильный тип, который соответствует протоколу в его определение.
Просто использование супертипов недостаточно, даже если в тесте № 3 очевидно, что данный экземпляр фактически соответствует протоколу HasChildren
.
Итак, что мне здесь не хватает, это просто невозможно? Есть ли у вас ссылки, содержащие больше информации о том, что происходит, или больше информации о предложениях where
, или подтипировании и его поведении в целом?
Я прочитал несколько полезных ресурсов, но ни один не кажется, исчерпывающее объяснение о том, почему он не работает:
Ну, это довольно очевидно, когда вы так говорите. Не могу поверить, что я пропустил это ... Думаю, моя идея рекурсивных общих функций не будет работать должным образом, если мы не сможем сделать их динамичными. –