Swift4 改进的private访问权限(SE-0169)

2017-08-28  本文已影响895人  LiuTianXiang

在Swift 3中,SE-0025对访问权限进行了改进,其中:
fileprivate
:用于定义只能在当前文件中访问的符号;
private
:用于定义只能在当前作用域以及子作用域中访问的符号;

绝大多数情况,它们都可以正常工作,但在Swift 3发布近一年之后,开发者发现这样的划分忽略掉了下面这样的场景:
假设,我们有一个机器人类,它有一个表示当前电量的属性:

class Robot {
    private var battery: Double = 0.5
}

在Swift 3里,如果我们要把充电的方法写在extension里,是无法通过编译的:

extension Robot {
    func charge() {
        battery = 1.0 // This will fail in Swift 3
    }
}

因为extension并不在Robot定义的作用域内部,但是像上面这种功能分组又很常见,于是,在Swift 3里,面对这种问题,很多开发者都使用fileprivate来替代private:

class Robot {
    // In Swift 3, sometimes we use `fileprivate`
    // instead of `private` for a larger access
    // scope.
    fileprivate var battery: Double = 0.5
}

但这并不是十全十美的解决方案,因为我们还可以在定义Robot的文件中编写这样的代码:

let r = Robot()
r.battery = 1.0

很明显,我们不应该允许这样的行为。所以,严格意义上说,我们期望的private访问权限要同时满足两个限制:

只在一个类型的“定义范围”中使用,这个范围同时包含了定义本身,以及类型的extension;
所有的extension必须和类型定义在同一个文件中,以防止外部代码也可以直接访问private属性;

而这,就是Swift 4中,对private权限的改进,现在你可以在Robot的定义,以及同文件内的所有extension Robot中,愉快的访问battery属性了:

class Robot {
    private var battery: Double = 0.5
}

extension Robot {
    func charge() {
        // This will sucess in Swift 4
        battery = 1.0
    }
}

let r = Robot()
// This still failed in Swift 4
r.battery = 1.0

原文链接

上一篇下一篇

猜你喜欢

热点阅读