看了很多篇介绍 Swift 2.0 的,感觉 Appcoda 这篇介绍的比较清楚,顺手学习并翻译了一下,英文原文看 这里 .
一年前,Apple 为 iOS 和 OSX 开发者带来了全新的编程语言 Swift,当苹果的副总裁在WWDC上宣布的那一刹那,我和很多开发者一样,异常兴奋。作为宣传中更快、更安全的语言,Swift 已经成长为目前最流行的语言了。在今年的 WWDC 上 Apple 推出了 Swift 2,我很幸运能参加这次 WWDC 大会,下面我分享一些新版 Swift 的更新。
We’re stepping on the gas this year with Swift 2. We think Swift is the next big programming language, the one we will all do application and systems programming on for 20 years to come. We think it should be everywhere and used by everyone.
Craig Federighi, Apple’s senior vice president of Software Engineering
我在 WWDC 会场注意到两次最大的掌声,一次是 Apple 宣布 Xcode 7 支持 UI testing,另一次就是 Swift 将开放源代码,后者将是一件大事件,今年晚些时候,Apple 将开发 Swift 的源代码给公众,包括编译器和一些基本库,这些都将在 OSI-compliant license 之下。苹果同样也将让 Swift 支持 Linux,开发者可以使用 Swift 来写系统应用了。这说明,苹果终于开始下功夫推动这门新生语言的发展了。
除去这些激动人心的新闻,Swift 2 介绍了一些新的功能,例如错误处理( error handling ),协议扩展( protocol extensions )和可用性检查( availability check ),下面我们来详细介绍下。
程序总会出错,当函数出错时,如果能找出哪里出错了,有助于理解为什么会失败。Swift 版本 1 缺乏合适的错误处理模式,在 Swift 2,终于加入了异常处理模式,使用 try / throw / catch 关键字。
想象一下有一辆汽车发动机,引擎会因为如下原因启动失败:
在 Swift 中,错误可以看做是遵守 ErrorType
协议的类型。据此,你可以创建一个遵守 ErrorType
的枚举模型来表示以上错误条件:
enum CarEngineErrors: ErrorType { case NoFuel case OilLeak case LowBattery }
要创建一个可以抛出异常的函数,你可以使用 throws 关键字:
func checkEngine() throws { }
要在函数中抛出一个错误,你可以使用 throw 语句,下面这个例子演示了检查发动机:
let fuelReserve = 20.0 let oilOk = true let batteryReserve = 0.0 func checkEngine() throws { guard fuelReserve > 0.0 else { throw CarEngineErrors.NoFuel } guard oilOk else { throw CarEngineErrors.OilLeak } guard batteryReserve > 0.0 else { throw CarEngineErrors.LowBattery } }
guard关键字是 Swift 2 为了增强控制流( control flow )推出的。当执行到控制分支 guard 语句,首先会检查后面紧跟的条件语句,如果条件为假,则 else 部分将会被执行,上面的例子中条件为假会执行 throw 语句抛出异常。
要调用 throwing function,你需要将 try 关键字放到函数名之前:
func startEngine() { try checkEngine() }
如果你在 Playgrounds 中写下上面的代码,你将会得到一个错误。Swift 的错误处理机制要求你必须使用 do-catch 语句来捕获所有的错误并处理他们。
下面这个函数指定了捕获到相关错误后打印相关错误信息:
func startEngine() { do { try checkEngine() print("Engine started", appendNewline: true) } catch CarEngineErrors.NoFuel { print("No Fuel!") } catch CarEngineErrors.OilLeak { print("Oil Leak!") } catch CarEngineErrors.LowBattery { print("Low Battery!") } catch { // Default print("Unknown reason!") } }
每个 catch 从句都匹配了特定的错误,然后指定了捕获到错误后应该做的事情。在上面的例子中, batteryReserve 变量被设置为 0,在这种情况下执行 startEngine()
, .LowBattery
错误将会被抛出。
将 batteryReserve 改为 1.0,这样汽车发动时就没有任何错误了。
类似于 switch 语句,Swift 2 的错误处理模型也是要求 完备 的,意味着你必须要处理全部可能的错误。这就是为什么我们要包含最后一个不带任何匹配模式的 catch
如果你想学习更多的关于 Swift 的错误处理,我推荐你去读 Apple 的 官方文档
看到这里,你可能已经注意到了 println()
函数不见了,在 Swift 2 中,我们只能使用 print()
来打印输出。Apple 将 println()
和 print()
合二为一。如果你想在新的一行打印,你可以设置 appendNewline
参数为 true
print("Engine started", appendNewline: true)
在第一版 Swift 中,你可以使用 extensions 为现有类、结构体、枚举类型添加新的功能。Swift 2 允许开发者将 extensions 带到了 protocol 类型上。通过 Protocol Extensions,你可以为遵守某个协议的类添加 properties 或 functions。当你想要扩展 protocol 的功能时将会变得非常有用。
还是通过一个例子来说明一下吧,创建一个 Awesome 协议,该协议提供一个返回 awesomeness(夸张)百分比,任何对象只要实现了该方法就可看做遵循此协议:
protocol Awesome { func awesomenessPercentage() -> Float }
现在我们声明了两个类遵守这个 Awesome
协议,每个类都实现了协议方法:
class Dog: Awesome { var age: Int! func awesomenessPercentage() -> Float { return 0.85 } } class Cat: Awesome { var age: Int! func awesomenessPercentage() -> Float { return 0.45 } } let dog = Dog() dog.awesomenessPercentage() let cat = Cat() cat.awesomenessPercentage()
如果你是在 Playground 中演示,将会得到如下输出:
假如你想要为 Awesome
协议添加一个 awesomenessIndex 属性,我们将使用 awesomenessPercentage() 方法来计算 awesomeness 索引:
extension Awesome { var awesomenessIndex: Int { get { return Int(awesomenessPercentage() * 100) } } }
通过在 protocol 上创建 extension,所有遵循该协议的类都将可以立即访问 awesomenessIndex 索引了。
是不是很美妙 O(∩_∩)O~~
每个开发者都要构建 App 的时候都要和不同的 iOS 版本做斗争。你总是希望使用最新的 API,但是当 APP 运行咋爱老版本 iOS 上的时候,会产生一些错误。在 Swift 2之前,没有一种可以进行 iOS 版本坚持的方式,比如 NSURLQueryItem 类只有在 iOS 8 上才能使用,如果你在之前的 iOS 版本中使用,会立即得到一个错误并且 crash 掉,为了预防这种事件的发生,你可以执行如下检查:
if NSClassFromString("NSURLQueryItem") != nil { // iOS 8 or up } else{ // Earlier iOS versions }
这是一种检查类是否存在的方式,从 Swift 2 开始,支持检查 API 在特定版本下的可用性了,你可以很容易地定义一个可用条件,然后在相应的代码块下执行与 iOS 版本相关的特定代码:
if #available(iOS 8, *) { // iOS 8 or up let queryItem = NSURLQueryItem() } else { // Earlier iOS versions }
经典的 do-while 循环现在被重命名为 repeat-while,貌似语意更加清晰了:
var i = 0 repeat { i++ print(i) } while i < 10
我希望你能很高兴地去阅读一下 Swift 2 的官方简介,这里有很多我这篇文章没有提到的内容,比如 Markdown 格式的注释等,你也可以去观摩 WWDC 视频 去学习更多 Swift 2 的内容。在此刻,仍然有相当多的公司将 Objective-C 作为 iOS 开发的主力语言,或许你也正使用 OC。但我强烈地相信 Swift 才是未来之路。事实上,WWDC 2015 所有的 sessions 都在使用 Swift,所以如果你还没有学习 Swift,现在就开始行动吧。
你可以下载这篇文章的 Playground file 代码 ,请确保用 Xcode 7 运行哦,因为这是唯一支持 Swift 2.0 的 Xcode 版本。