为什么 swift 隐藏受限协议的默认实现?
Why does swift hide default implementation for restricted protocols?
我有一个声明如下所示的协议:
protocol RefreshableView where Self: UIView {
func reload()
}
它有默认实现,如下所示:
extension RefreshableView {
func reload() {
print("Default implementation")
}
}
然后,如果我声明 UIView
的另一个(空)扩展符合此协议,我会收到编译时错误,指出 UIView
不符合协议。
extension UIView: RefreshableView {}
从我的角度来看,这不应该是一种情况,因为提供了默认实现。但是,如果我从协议声明中删除 where
语句(对可以符合协议的 类 的限制),一切都会按预期进行。消除此错误的另一种选择是在默认扩展声明旁边提供相同的 where
语句,但感觉是多余的,因为我已经让编译器知道该协议适用于少数受众。对这种行为有解释吗?
你的意思是这不能编译:
protocol RefreshableView where Self: UIView {
func reload()
}
extension RefreshableView {
func reload() {
print("Default implementation")
}
}
extension UIView: RefreshableView {
}
正如 Rob Napier 在评论中指出的那样,这是一件非常奇怪的事情,因为如果 UIView 本身 将采用 RefreshableView,那么协议的用途是什么?协议的原始声明意味着只有 UIView 子类 可以采用 RefreshableView,所以编译器期望的是会发生什么:
protocol RefreshableView where Self: UIView {
func reload()
}
extension RefreshableView {
func reload() {
print("Default implementation")
}
}
class MyView: UIView {}
extension MyView: RefreshableView {
}
这是一个有用的真实案例,编译得很好。
因此您可以针对您的原始代码提交错误,但您必须承认这一点
一开始是一个非常特殊的边缘案例;你说的是实际上没有人会说的话。
我有一个声明如下所示的协议:
protocol RefreshableView where Self: UIView {
func reload()
}
它有默认实现,如下所示:
extension RefreshableView {
func reload() {
print("Default implementation")
}
}
然后,如果我声明 UIView
的另一个(空)扩展符合此协议,我会收到编译时错误,指出 UIView
不符合协议。
extension UIView: RefreshableView {}
从我的角度来看,这不应该是一种情况,因为提供了默认实现。但是,如果我从协议声明中删除 where
语句(对可以符合协议的 类 的限制),一切都会按预期进行。消除此错误的另一种选择是在默认扩展声明旁边提供相同的 where
语句,但感觉是多余的,因为我已经让编译器知道该协议适用于少数受众。对这种行为有解释吗?
你的意思是这不能编译:
protocol RefreshableView where Self: UIView {
func reload()
}
extension RefreshableView {
func reload() {
print("Default implementation")
}
}
extension UIView: RefreshableView {
}
正如 Rob Napier 在评论中指出的那样,这是一件非常奇怪的事情,因为如果 UIView 本身 将采用 RefreshableView,那么协议的用途是什么?协议的原始声明意味着只有 UIView 子类 可以采用 RefreshableView,所以编译器期望的是会发生什么:
protocol RefreshableView where Self: UIView {
func reload()
}
extension RefreshableView {
func reload() {
print("Default implementation")
}
}
class MyView: UIView {}
extension MyView: RefreshableView {
}
这是一个有用的真实案例,编译得很好。
因此您可以针对您的原始代码提交错误,但您必须承认这一点 一开始是一个非常特殊的边缘案例;你说的是实际上没有人会说的话。