我正在尝试理解为什么通用方法的where子句被忽略。
我在Swift 3中制作了一个简单的用例(如果您想要玩弄它,可以将代码复制到playground中):
输出结果为:
我在Swift 3中制作了一个简单的用例(如果您想要玩弄它,可以将代码复制到playground中):
//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
从句、子类型和一般行为的信息吗?
我已经阅读了一些有用的资源,但似乎没有详尽的解释为什么它不起作用: