使用从另一个协议继承或使用 where Self 声明 swift 协议时的区别

Difference when declaring swift protocol using inheritance from another protocol or using where Self

我仍然不明白使用继承声明 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来约束它更有意义,这样reader就可以知道谁实现了它也需要符合 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
    }
}

如果有人能向我解释有什么区别,我将不胜感激

提前致谢。

说到Swift5,两种形式没有区别,见Swift 5 Release notes:

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)