具有计算属性的协议

Niv*_*Niv 8 swift swift-extensions swift-protocols

是否有特定原因限制我们在protocol声明中提供计算属性?因为我们只有机会将这些计算属性设置extensionprotocol.

单词 -> 代码:

为什么这不起作用-(背后的逻辑是什么)

protocol GridableGraph {
    
    var yTick: Float { get }
    var yTicksCount: Int { get }
    
    var xTick: Float{ get }
    var xTicksCount: Int { get }

    var maxYValue: Float { return Float(yTicksCount - 1) * yTick }
    var maxXValue: Float { return Float(xTicksCount - 1) * xTick }
}
Run Code Online (Sandbox Code Playgroud)

虽然这确实

protocol GridableGraph {
    
    var yTick: Float { get }
    var yTicksCount: Int { get }
    
    var xTick: Float{ get }
    var xTicksCount: Int { get }
}

extension GridableGraph{
    var maxYValue: Float { return Float(yTicksCount - 1) * yTick }
    var maxXValue: Float { return Float(xTicksCount - 1) * xTick }
}
Run Code Online (Sandbox Code Playgroud)

vrw*_*wim 3

协议旨在提供一个接口(一组方法和属性),但将实现留给实现类。

当您对协议进行扩展时,我们决定让这些扩展需要实现,以免弄乱库或框架内的代码。

假设您想UITableViewDataSource用您喜欢的方法扩展协议。如果 Swift 不需要实现,那么所有使用该协议的UIViewControllers人会发生什么?UIKit从技术上讲,您可以调用该方法,但您会收到错误,因为该方法不存在。

Swift 通过在扩展协议时要求实现来解决这个问题。这样,您可以不实现它(使用默认实现)或实现它(使用类中的实现)。这是因为 Apple 希望 Swift 尽可能安全。

编辑:您没有问为什么扩展需要默认实现,您问为什么不能将默认实现放在您的 中protocol,而是需要将其放在extension. 我想这是因为 Swift 喜欢保持一致,并且因为他们已经允许协议扩展中的默认实现,所以他们可能还需要默认实现。

请记住,在同一文件中使用多个扩展名没有任何问题,甚至建议将其作为拆分代码的首选方式,以便在Ray Wenderlich Swift 风格指南中更好地进行概述。