使用其他协议的继承或在何处使用Self声明快速协议时的区别

时间:2019-07-12 03:53:47

标签: swift swift-protocols

在使用继承声明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
    }
}

如果有人可以向我解释一下,我会很感激?

谢谢。

1 个答案:

答案 0 :(得分:2)

谈到Swift5,这两种形式没有区别,请参见Swift 5 Release notes

  

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

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

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