WWDC之What's new in Swift
前言
此为WWDC2015上对Swfit语言2.0版本的改进和新特性做了一个快速介绍的Session,主要由Swift语言创造者Chris Lattner演讲.从中可以大致地了解Swift 2.0中主要变化:
- 基础改进
- 新增多种模式匹配形式
- API可用性检查
- 实现对协议扩展
- 进行错误处理
内容
基础改进
-
Enum
1.对枚举类型变量进行
print
时,将进行枚举类型具体值的明确输出.(swift1.x: 只输出所属的枚举类型,不具体)示例
enum Direction { case East, South, West, North } let direction:Direction = Direction.East print(direction) //output: East
2.枚举关联值的类型支持泛型
使得枚举内部关联值的类型可以在调用时进行指定.使得自己可以实现类似Optional类型的枚举.
示例
enum myOptional<T> {
case myNone
case mySome(T)
}
var a: myOptional<Int> = .myNone // 使用前必须要让该枚举范特定类型才能使用
a = .mySome(1)
3.枚举递归调用
为解决一些代数,算法问题时遇到需要递归方法解决时,使用indirect
关键字,目前只针对enum类型
示例
enum Tree<T> {
case Leaf(T)
indirect case Node(Tree, Tree)
}
let leftTree:Tree<Int> = .Leaf(121)
let rightTree:Tree<Int> = .Leaf(50)
let subTree:Tree<Int> = .Node(leftTree, rightTree)
print(subTree)
//output: Node(Tree<Swift.Int>.Leaf(121), Tree<Swift.Int>.Leaf(50))
-
循环语句
使用新的关键字repeat
代替do
(其关键字作用于错误处理),进行循环操作.
示例var count = 0; repeat { print("it's \(count++) counts") } while (count < 5)
-
选项集合的处理
针对Cocoa框架中众多的Options参数,其类型,值都各不相同,判断包含关系时通过原始的Bitwise方式,还很容易出错,Swift2.0推出OptionSetType协议,让所有选项集合都遵守该协议,根据协议提供API来检查包含,并存关系.示例
struct VolumeOption: OptionSetType { let rawValue: Int static let SoundClose = VolumeOption(rawValue: -1) static let SoundOpen = VolumeOption(rawValue: 1) static let VolumeUp = VolumeOption(rawValue: 2) static let VolumeDown = VolumeOption(rawValue: 3) } var v:VolumeOption = [.SoundOpen, .VolumeUp, .VolumeDown] if v.contains(.SoundOpen) { print("Sound is available !") } //output: Sound is available !
-
函数和方法的参数标签统一
对于全局函数和类的方法都同一将其首个参数标签省略(内部使用_
进行参数标签的省略), 其他参数标签默认与内部参数名相同,也可以自己定义不同的参数标签;取消了#
+内部标签的标签命名形式.
示例func save(name: String, encrypt: Bool){ //.. } class Widget { func save(name: String, encrypt: Bool){ //.. } } save("global", encrypt: true) let widget = Widget() widget.save("internal", encrypt: true)
模式匹配
- if-let形式的可选绑定可以进行复合操作(多个可选,同一if下进行绑定),还可配合where进行条件限定
示例let x: Int? = 10 let y: String? = "wrcj" let z: Bool = true if let x = x, let y = y where z == true { print("x's value:\(x), y's value:\(y)") } //output: x's value:10, y's value:wrcj
- 提供新式
guard-else
的可选绑定,当可选类型变量为nil时直接对方法进行返回,有值情况下使用绑定后的新变量
示例let num: Int? = 100 guard let aNum = num else { fatalError() } print(aNum) //output: 100
- 提供if-case的模式匹配,为简化Switch操作中只针对一个case进行比配的情况处理,直接使用
if case..
句式提供指定case的匹配.
示例if case .mySome(let v) = a where v > 10 { print("the value isn't none, and greater than 10") } //: output:the value isn't none, and greater than 10
- 允许对for...in的遍历对象进行模式匹配,使用
where
关键字
** 示例**let array = [1,2,3,4,5] for value in array where value % 2 == 0 { print(value ) } //: output: 1 3 5
API可用性检查
- 编译器会根据当前支持的最低系统SDK来检查存在可能会出现不兼容的新API的代码,并提示错误进行修正.
- 舍弃
Objective-C
的判断方法是否可响应的API:respondsToSelector
,使用一个宏进行API可用if条件判断,若允许则在if内部使用新API
示例if #available(iOS 9.0, *) { // new 9.0 API } else { // old API }
实现对协议扩展
Swift 2.0后除了对已存在的类写extension
进行方法扩展外(类似Objective-C
的分类),也允许对协议进行方法扩展,并且在扩展方法中要完成默认实现代码,也意味着Protocol中的方法允许存在默认实现,即只要遵守该协议,就能进该协议默认实现方法的调用,也使得Swift成为一门面向协议的编程语言.
示例
extension CollectionType {
func countIf(match: Generator.Element -> Bool) -> Int {
var n = 0
for value in self {
if match(value) { n++ }
}
return n
}
}
let aSet = [1,2,3,4,5,6,7,8,9]
let counts = aSet.countIf { (num) -> Bool in
if num >= 5 {
return true
} else {
return false
}
}
print("the counts is \(counts)")
//: output:the counts is 5
错误处理
应对Cocoa API
各种可能出现错误的地方,Swift 2.0以前使用NSError对象指针传递错误,若存在错误则将为该指针赋值一个NSError
对象,为了检测错误需要添加许多胶水代码.现在Swift 2.0推出的对错误捕获的try-catch
特性,允许对错误先进行捕获再自定义行为.
示例
num DataFetchError: ErrorType {
case MissingData
case MissingSource
case NetworkUnavailable
}
func fetchDataOnline(json: AnyObject) throws {
guard let result = json["result"] as? Int else {
throw DataFetchError.NetworkUnavailable
}
guard let source = json["source"] as? NSDictionary else {
throw DataFetchError.MissingSource
}
guard let data = json["data"] as? NSDictionary else {
throw DataFetchError.MissingData
}
print("reuslt:\(result), source:\(source), data:\(data)")
}
func getData () {
do {
try fetchDataOnline("no data")
} catch DataFetchError.NetworkUnavailable {
print("NetworkUnavailable")
}catch DataFetchError.MissingData {
print("MissingData")
} catch DataFetchError.MissingSource {
print("MissingSource")
} catch let error {
print(error)
}
}
Notes 错误处理中的try还有两种使用形式:
- try! + 方法调用: 表示该方法若出现错误,则直接Crash程序;
- try? + 方法调用: 表示该方法若出现错误,其方法返回值为nil(配合可选类型适用),不做额外的错误处理;
结尾
作为Swfit 2.0内容介绍的第一部Session,其中许多新特性都会在之后更多的Session中进行重点的演示和说明.总之,Swift逐渐着成熟完善,朝着让开发者可以更容易地写出漂亮,可读,高效的代码的目标不断前行着.