Swift 3.0 beta 6权限访问修改

前两天 swift 3.0 更新了 beta 6, 权限访问的几个关键字有了一些改变, 这篇文章给大家简单介绍一下(真得很简单…)

还有一些小改变, 其中几个让人觉得很诡异:

  • 很多 Core xx 的库把 swift原生的 Array 改成了 CFArray, 很多时候需要用 as 去转换(swift runtime 目前唯一一个比较显眼的功能…)
  • 声明闭包的时候不能带显式 argument label, 例如typealias completion = (data: Data, error: Error?) -> Void就会报错, 必须加上_或者删掉参数标签
  • 还有就是现在闭包声明的时候默认都是@nonescaping的, 如果闭包不是在当前作用域内执行而是还要继续作为参数传递到别的函数里的话, 那就必须加上@escaping
  • 引入了 Objective-C 的 id, 在 Swift 叫做Any, 之前很多接口都从 AnyObject 改成了 Any, 而 Any 是没有 subscript 方法的, 看也就是说不能用键值对取值, 很多原本要通过键值对取值的写法都得先把类型强转成字典或者是 Anyobject?

新增 open 关键字, public 变得没那么 public

beta 6 新增加了 open 关键字, 可以理解为之前的 public

在同一个包 module 内, public 跟 open 的含义是一样的, 但是在 module 外, open 声明的成员变量和函数是可以被 override 的, 而 public 只是把接口公开出去, 而不能被 override

open 大概有这么几个规则:

  • 一个类可以被声明为 open.
  • 一个类不能同时声明 openfinal
  • 一个 open 的类的父类必须也是 open 的, 父类的父类也必须会被按照这条规则递归约束

这个主要是区分开 Module 外可访问Module 外可被修改这两个概念, 具体可以看[SE-0117]Allow distinguishing between public access and public overridability提案

//--------Module Foo-------
class Foo {
public var one: Int {
return 1
}
open var two: Int {
return 2
}
}
class A: Foo {
// 正常运行
override var one: Int {
return 2
}
// 正常运行
override var two: Int {
return 1
}
}
//------End of Module------
//--------Module Bar-------
class B: Foo {
// 报错
override var one: Int {
return 2
}
// 正常运行
override var two: Int {
return 1
}
}
//------End of Module------

另外还有一点, 就是 Objective-C 的库导入的话默认都为 open, 之前是 public

新增moduleprivatefileprivate, 而 private 变得更加 private

这一次还新增了一个 moduleprivate, 从字面意义上来说跟 internal 很像, 我现在还不太清楚到底跟 internal 有什么具体的区别, 在 Swift Evolution 和 Xcode 的 Release Note 里都没有找到具体的解释

为了权限安全, 我们很多时候都会在变量和实现的函数前面加上 private, 现在需要改成 fileprivate, fileprivate 跟之前的 private 基本上一样

private 现在就更加 private, 只能在当前作用域内发生作用, 同一文件里 extension 里也是不能访问的到 private 修饰的成员变量

//---- 文件 Foo.swift ----
class {
fileprivate var one = 1
private func two() {...}
}
extension Foo {
func printOne() {
print(one) // 正常运行
}
func printTwo() {
print(two) // 报错
}
}
//--------- EOF ---------
//-- 文件 Foo+Bar.swift --
extension Foo {
// 都报错
func printOneAgain() {
print(one)
}
func printTwoAgain() {
print(two)
}
}
//--------- EOF ---------

参考链接

What is the ‘open’ keyword in Swift?

[SE-0117]Allow distinguishing between public access and public overridability

#22 Swift 3 Access Control (Xcode 8 Beta 6)