如果需要实现已被废弃的 var 参数的功能(在函数内部修改参数值,函数外部不可见),可以采用声明变量覆盖同名参数的办法
func f(i: Int) { // i += 1 // ERROR var i = i i += 1 } let x = 3 f(x) // x == 3 试比较: func f(i: inout Int) { i += 1 } var x = 3 f(&x) // x == 4无参数的闭包在形式上可以和代码块相同,需要根据上下文加以区分。
let a = 3 let f1 = { () -> Bool in return a % 2 == 0 } // 闭包 let f2 = { () -> Bool in a % 2 == 0 } // 闭包 let f3 = { () in return a % 2 == 0 } // 闭包 let f4 = { () in a % 2 == 0 } // 闭包 let f5 = { return a % 2 == 0 } // 闭包(形式上和代码块相同) let f6 = { a % 2 == 0 } // 闭包(形式上和代码块相同) func f7() -> Bool { // 函数 return a % 2 == 0 } let b = f1() || f2() || f3() || f4() || f5() || f6() || f7() // b == falseIntroducing Protocol-Oriented Programming in Swift 2
将 Mixin 实现为协议。通过协议扩展来为 Mixin 提供缺省实现。采纳该协议以完成 Mixin 功能。 protocol SampleMixin { var sampleProperty: Int { get } func sampleMethod() } extension SampleMixin { var sampleProperty: Int { return 42 } func sampleMethod() { print("default implementation") } } class SampleClass : SampleMixin {} let c = SampleClass() c.sampleMethod() // default implementation print(c.sampleProperty) // 42模式匹配并不仅仅局限于switch语句,在if,guard以及for语句中也能进行模式匹配。 Swift 2: Pattern Matching with “if case” Pattern Matching, Part 4: if case, guard case, for case
// if case语句实现模式匹配 enum Media { case book(title: String, author: String, year: Int) case movie(title: String, director: String, year: Int) case webSite(urlString: String) } let m = Media.movie(title: "Captain America: Civil War", director: "Russo Brothers", year: 2016) if case let Media.movie(title, _, _) = m { print("This is a movie named \(title)") } // 相当于 switch m { case let Media.movie(title, _, _): print("This is a movie named \(title)") default: break } // if case语句实现模式匹配 if case 1...255 = x {} // 相当于 if 1 <= x && x <= 255 {}需要新开一个作用域时,不能像其他C系列语言那样直接写大括号,不然会出现如下错误: statement cannot begin with a closure expression(语句不能以闭包表达式开头) 正确方法是使用不带 catch 的 do 语句。
defer语句在当前作用域即将结束时执行指定的代码块,相当于其他语言的try...finally。 如果某个作用域内存在多个defer语句时,该作用域即将结束时排在后面的defer语句所指定的代码块先执行,排在前面的defer语句所指定的代码块后执行。 The defer keyword in Swift 2: try/finally done right
// do语句 + defer语句 print("Step 1") do { defer { print("Step 2") } defer { print("Step 3") } print("Step 4") print("Step 5") } print("Step 6") /* Step 1 Step 4 Step 5 Step 3 Step 2 Step 6 */使用 public private(set) 创建 public 只读 private 可写的变量。 Public Read-only Variables
// private(set) public class Person { public private(set) var name: String // ... }使用元组+模式匹配或者字符串形式来比较两个带相关值的枚举。 How to test equality of Swift enums with associated values
// 比较两个带相关值的枚举 enum SimpleToken : Equatable { case name(String) case number(Int) } let t1 = SimpleToken.number(123) // the string representation is "number(123)" let t2 = SimpleToken.number(123) let t3 = SimpleToken.name("bob") // the string representation is "name(\"bob\")" // 字符串形式 print(String(describing: t1) == String(describing: t2)) // true print(String(describing: t1) == String(describing: t3)) // false // 元组+模式匹配 func == (lhs: SimpleToken, rhs: SimpleToken) -> Bool { switch (lhs, rhs) { case let (.name(a), .name(b)): return a == b case (.name, _): return false case let (.number(a), .number(b)): return a == b case (.number, _): return false } } print(t1 == t2) // true print(t1 == t3) // falseSwift 中最短的空语句不是分号而是一对小括号。
switch true { default: // ; // error: ';' statements are not allowed () do{} {}() break }Advanced & Practical Enum usage in Swift