ios - 为什么 swift 隐藏受限协议(protocol)的默认实现?

标签 ios swift swift-protocols swift-extensions

我有一个声明如下所示的协议(protocol):

protocol RefreshableView where Self: UIView {
    func reload()
}

它有默认实现,如下所示:

extension RefreshableView {
    func reload() {
        print("Default implementation")
    }
}

然后,如果我声明 UIView 的另一个(空)扩展符合此协议(protocol),我会收到编译时错误,指出 UIView 不符合协议(protocol)。

extension UIView: RefreshableView {}

从我的角度来看,这不应该是一种情况,因为提供了默认实现。但是,如果我从协议(protocol)声明中删除 where 语句(对可以符合协议(protocol)的类的限制),一切都会按预期进行。消除此错误的另一种选择是在默认扩展声明旁边提供相同的 where 语句,但感觉多余,因为我已经让编译器知道该协议(protocol)适用于少数受众。对这种行为有解释吗?

最佳答案

你的意思是这不能编译:

protocol RefreshableView where Self: UIView {
    func reload()
}
extension RefreshableView {
    func reload() {
        print("Default implementation")
    }
}
extension UIView: RefreshableView {
}

正如 Rob Napier 在评论中指出的那样,这是一件非常奇怪的事情,因为如果 UIView 自身 将采用 RefreshableView,那么协议(protocol)的用途是什么?协议(protocol)的原始声明意味着只有 UIView 子类 可以采用 RefreshableView,因此编译器期望的是将发生的事情:

protocol RefreshableView where Self: UIView {
    func reload()
}
extension RefreshableView {
    func reload() {
        print("Default implementation")
    }
}
class MyView: UIView {}
extension MyView: RefreshableView {
}

这是一个有用的真实案例,它编译得很好。

因此您可以针对您的原始代码提交错误,但您必须承认这一点 一开始是一个非常特殊的边缘案例;您说的是实际上没有人会说的话。

关于ios - 为什么 swift 隐藏受限协议(protocol)的默认实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57887989/

相关文章:

swift - 泛型方法中 T 和 Self 的区别

objective-c - 在 Swift 中填充 NSRectPointer

ios - Firebase - 当您不知道父键的值时访问子节​​点 - 由 childByAutoId() 生成

swift - setValue() 同时创建和删除值

ios - 使用 2 个类/委托(delegate) Swift 从另一个单元格控制 UITableView 单元格的内容

swift - 在泛型函数中使用协议(protocol)的关联类型

ios - UITextView 在 iPhone 6+ 中自动改变颜色,这不是必需的

ios - 类型 'UIImageView' 的值没有成员 'setImageWith'

ios - uniqueIdentifier 与 indentifierForVendor 和 Apple 拒绝

iphone - 如何将本地 HTML 文件加载到 UIWebView 中?