Swift3新特性(What's New in Swift)

前言

Swift3即将发布release版本,WWDC2016上苹果也带来了介绍.点击这里看视频.本文主要是翻译和解释.另外原视频前面介绍了Swift是怎么开源的,最后谈到了如何提高效率.对于一般开发者并无大用,我这里也就不多说了.

API简化

许多API是从OBjective-C版本直接转成Swift版本,所以不够Swift化.苹果在Swift3中简化了大量API,使其语义更清晰,语法更简洁.举例如下:

// Swift 2
array.appendContentsOf([2,3,4])
array.insert(1, atIndex: 0)
// Swift 3
array.append(contentsOf: [2,3,4])
array.insert(1, at: 0)

// Swift 2
if url.fileURL {}
x = url.URLByAppendingPathComponent("file.txt")
// Swift 3
if url.isFileURL {}
x = url.URLByAppendingPathComponent("file.txt")

Objective-C API优化

1. Swift化
Objective-C中存在着大量的C式API,在Swift中显得格格不入.在Swift3中得以改进.如:

// Swift 2
func CGContextFillPath(_: CGContext)
// Swift 3
void CGContextFillPath(CGContextRef) NS_SWIFT_NAME(CGContext.fillPath(self:));
extension CGContext {
  func fillPath()
}

2. Objective-C泛型支持
Objective-C本身是不支持泛型的,当我们使用某些通用的API是就相当痛苦.比如使用Core Data查询得到的结果,明明可以指定类型.在Swift3中是这样改进的:

// Swift 2
func findAnimals() {
  let request = NSFetchRequest(entityName:”Animal")
  guard let searchResults =
       try? context.executeFetchRequest(request) as! [Animal] {
    return
  }
  ...
  use(searchResults)
}
// Swift 3
func findAnimals() {
  let request : NSFetchRequest = Animal.fetchRequest
  guard let searchResults = try? context.fetch(request) {
    return
  }
  ...
  use(searchResults)
}

这里的guard语句的else漏掉了,我怀疑是演讲稿有问题,并不是修改了

3. String型的Enum改进
在Objective-C中String型的Enum到处可见(与C语言相关).而String的不安全性很大.使用者可以随意传入String从而导致Bug.在Swift3中对此也进行了优化.

// Swift 2
typedef NSString *NSNotificationName;
const NSNotificationName NSUserDefaultsDidChangeNotification;
let NSUserDefaultsDidChangeNotification: String  //  Imported definition
center.addObserver(forName: NSUserDefaultsDidChangeNotification, ...) // Use

// Swift 3
typedef NSString *NSNotificationName;NS_EXTENSIBLE_STRING_ENUM; 
const NSNotificationName NSUserDefaultsDidChangeNotification;
extension UserDefaults {
  class let didChangeNotification: NSNotification.Name
}  //  Imported definition
center.addObserver(forName: UserDefaults.didChangeNotification, ...) // Use

Core Language(语言特性)

1. 参数标签
首先就是方法的首个参数名称不再默认略去(这是Objective-C的命名特点).如:

func myFunction(a: Int, b: Int, c: Int) { } 
// Swift 2
myFunction(42, b: 57, c: 99)
// Swift 3
myFunction(a: 42, b: 57, c: 99)

2. 泛型约束
泛型的约束条件过长引起阅读困难,将where部分挪至函数尾部.如:

// Swift 2
func anyCommon(lhs: T, rhs: U) -> Bool {
// Swift 3
func anyCommon(lhs: T, rhs: U) -> Bool where T.Element: Equatable, T.Element == U.Element {

3. 未使用返回值警告
现在允许将函数标记为@discardableResult用于不使用返回值且不警告.

@discardableResult
func plusOne(_ a: Int) -> Int {
  print(a)     // side effect!
  return a+1
}
plusOne(4) // no warning

类型系统

1. UnsafeMutablePointer
在Swift2中可以将nil直接赋给UnsafeMutablePointer,苹果原本就是把UnsafeMutablePointer对待成不安全的指针.但是Swift3中苹果不愿再将其特殊化, UnsafeMutablePointer将与其他类型一样有可选型.

// Swift 3
let ptr : UnsafeMutablePointer = nil
let ptr : UnsafeMutablePointer? = nil

2. 隐式可选型
隐式可选型为用!修饰的类型,它可以为nil,而且可以传给要求非nil的参数.不过当访问此值时会强制解包,如果为nil则会引起崩溃.Swift3中针对非可选型与隐式可选型相加得到的结果类型进行了改变.

func f(value : Int!) {
  let x = value + 1 // x: Int - force unwrapped 
  let y = value // Swift2中 y: Int!, Swift3中 y: Int?
}

标准库

1. Collection的新Index
Swift对于Index的处理一直让人感觉捉襟见肘,Swift3中对于语法进行了改进.具体如下:

// Swift 2
i = collection.startIndex
next = i.successor()
// Swift 3
i = collection.startIndex
next = collection.index(after: i)

其他的改进还有:

  • 半开区间和区间并入Range型
  • 0...UInt8.max现可以正确生效
  • 性能提升

2. 浮点数和数值
浮点数包含Float,Float80,Double和CGFloat.我想很多人应该疲于浮点型间的类型转换以及运算.在Swift3中pi值可以在任何浮点型中get到.而且浮点型间的运算无需再频繁转换.代码如下:

let v = 2 * Float.pi                 // 轻松get pi值
return x * CGFloat.pi / 180   // Float间运算无需转换

附录

关于新版本的改动还有非常多,有一些是一笔带过的,还有更多是没有提到的.在这里我以附录的形式呈现给大家,也方便以后补充.

  • 柯里化函数声明被删除
  • 函数参数声明不可使用var修饰(Closure一样)
  • ++和--运算符被删除
  • C式循环被删除 for (i=0;i<10;i++)...
  • 移除了隐式元组
  • 新增fileprivate访问级别
  • case关键字可与多变量绑定
  • 泛型支持别名(Type Aliases)

你可能感兴趣的:(Swift3新特性(What's New in Swift))