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



我仍然不明白使用继承声明 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
}
}

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

提前谢谢。

说到 Swift5,这两种形式之间没有区别,请参阅 Swift 5 发行说明:

协议现在可以将其符合类型限制为对给定类进行子类化的类型。支持两种等效形式:

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

Swift 4.2 接受了第二种形式,但它没有完全实现,有时会在编译时或运行时崩溃。(SR-5581)(38077232)

最新更新