使用继承另一个协议声明 Swift 协议和使用 where Self 的区别

4

我仍然不明白使用继承声明Swift协议的区别是什么:

protocol SubProtocol: SuperProtocol { ... }

或者使用 where Self

protocol SubProtocol where Self: SuperProtocol { ... }

通过这两种方式,结果完全一样,两个选项都可以编译通过并能正常工作,“SubProtocol”将与“SuperProtocol”拥有相同的内容。那么差异在哪里呢?
我只能看到一个语义上的区别,其中一个更清晰明了(见下面的例子)。但这是我的观点,我想知道是否还有其他人持有相同看法,或者我是否误解了整件事情。
示例:
protocol Progressable {
    var isInProgress: Bool { get }
}

protocol Downloadable: Progressable {
    func download()
}

protocol ProgressReporting where Self: Progressable {
    func reportProgress() -> Bool
}

对我来说,Downloadable 继承自 Progressable 是有意义的,每个下载都是可进度的,所以这没问题。

但是我认为 ProgressReporting 并不一定需要继承自 Progressable,使用 where 约束更有意义,这样读者就知道实现它的人也需要符合 Progressable(请参见下面代码中的注释),这时我认为语义是不同的。

class MyClassA: Downloadable {
    var isInProgress: Bool { return true }
    func download() {}

    func foo() {
        /*
         I have access to `self.isInProgress` because this class conforms `Downloadable`
         which inherits from `Progressable`, so this makes sense
         */
        _ = self.isInProgress
    }
}

class MyClassB: ProgressReporting {
    var isInProgress: Bool { return true }
    func reportProgress() {}

    func foo() {
        /*
         I have access to `self.isInProgress` but according to `ProgressReporting` definition,
         this class should be `Progressable` which is not, at least not explicitely
         */
        _ = self.isInProgress
    }
}

我希望有人能够解释一下它们的差异。

提前感谢。


我认为where方法可能会对Self施加要求,但是没有建立类型关系,即符合SubProtocol的任何内容也将传递符合SuperProtocol(例如Hashable/Equatable的情况)。但事实并非如此,它们在这方面的工作方式相同:https://repl.it/@alexandermomchilov/Protocols-colon-vs-Self-requirment - Alexander
1个回答

2

提到Swift5,这两种形式没有区别,请参见Swift 5发布说明

原始答案:Original Answer

Protocols can now constrain their conforming types to those that subclass a given class. Two equivalent forms are supported:

protocol MyView: UIView { /*...*/ }
protocol MyView where Self: UIView { /*...*/ } 

Swift 4.2 accepted the second form, but it wasn’t fully implemented and could sometimes crash at compile time or runtime. (SR-5581) (38077232)


太棒了!这正是我在寻找的!谢谢! - rgkobashi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接