From c4a3752c53eaf7cd9ca4bd17b518b4ed8f8e83c3 Mon Sep 17 00:00:00 2001 From: AceVest Date: Sun, 19 Jun 2016 22:15:52 +0800 Subject: [PATCH] swift:functions & closures --- .../AcePlay/AcePlay.playground/Contents.swift | 8 -- .../Basics.xcplaygroundpage/Contents.swift | 104 ++++++++++++++ .../Closure.xcplaygroundpage/Contents.swift | 130 ++++++++++++++++++ .../Functions.xcplaygroundpage/Contents.swift | 56 ++++++++ .../AcePlay.playground/Sources/Basic.swift | 105 -------------- .../AcePlay.playground/Sources/Func.swift | 13 -- .../AcePlay.playground/contents.xcplayground | 8 +- .../UserInterfaceState.xcuserstate | Bin 12776 -> 13902 bytes 8 files changed, 296 insertions(+), 128 deletions(-) delete mode 100644 learn/AcePlay/AcePlay.playground/Contents.swift create mode 100644 learn/AcePlay/AcePlay.playground/Pages/Basics.xcplaygroundpage/Contents.swift create mode 100644 learn/AcePlay/AcePlay.playground/Pages/Closure.xcplaygroundpage/Contents.swift create mode 100644 learn/AcePlay/AcePlay.playground/Pages/Functions.xcplaygroundpage/Contents.swift delete mode 100644 learn/AcePlay/AcePlay.playground/Sources/Basic.swift delete mode 100644 learn/AcePlay/AcePlay.playground/Sources/Func.swift diff --git a/learn/AcePlay/AcePlay.playground/Contents.swift b/learn/AcePlay/AcePlay.playground/Contents.swift deleted file mode 100644 index 2a17f16..0000000 --- a/learn/AcePlay/AcePlay.playground/Contents.swift +++ /dev/null @@ -1,8 +0,0 @@ -//: Playground - noun: a place where people can play - -import UIKit - - -SwiftBasics() - -SwiftFunctions() diff --git a/learn/AcePlay/AcePlay.playground/Pages/Basics.xcplaygroundpage/Contents.swift b/learn/AcePlay/AcePlay.playground/Pages/Basics.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..1ff1148 --- /dev/null +++ b/learn/AcePlay/AcePlay.playground/Pages/Basics.xcplaygroundpage/Contents.swift @@ -0,0 +1,104 @@ +//: Playground - noun: a place where people can play + +import UIKit + +let str = "Hello, playground.小狗:🐶 锤子:🔨" + +// Index +let strInx:String.Index = str.startIndex +strInx.successor() +print(strInx) + +for c in str.characters { + print(c, terminator: "") +} +print() + +// Print separator & terminator +var company:Array = [ "Apple", "Google", "Facebook", "Tencent" ] +print(company[0], company[1], company[2], company[3], separator: "#", terminator: " $$$$$\n") + +printLine("Count company Array 1") +for (i,v) in company.enumerate() { // enumerate 返回的是 index value 组成的元组 + print(i, v, separator: " - ", terminator: "\n") +} + +printLine("Count company Array 2") +company.insert("Alibaba", atIndex: company.count) +for i in 0..(0.. = [] +var SetB = Set() +var SetC: Set = ["ASM", "C", "C++", "go", "Swift"] +//var SetD: Set = ["mov", "pop", "push", "xchg"] // 可以通过数组类型推断出Set的类型 +SetB.insert("A") +SetB.insert("c") +SetB.insert("c") +SetB.count +//SetC.removeFirst() +SetC.remove("ASM") + +if let removedVal = SetC.remove("ASM") { + print("\(removedVal) I'm over it.") +} else { + print("I never much cared for that.") + SetC.insert("ASM") +} + +if SetC.contains("Swift") { + print("SetC Contains Swift") +} + +for v in SetC.sort() { + print(v) +} + +printLine("Dictionary") +//var DictA = Dictionary() +//var DictB = ["KA":"VA", "KB":"VB", "KC":"VC"] +//var DictC: [String:String] = [:] +var DictD = [Int:String]() + +DictD[1] = "V1" +DictD[4] = "V2" +DictD[99] = "V3" +DictD[36] = "F4" +if let oldValue = DictD.updateValue("V4", forKey: 36) { // means: if let oldValue = DictD[36] + print("The old value for Key:36 was \(oldValue)") +} + +print("DictD Item Count: ", DictD.count) + +for (k, v) in DictD { + print("Key:", k, " Value: ", v) +} + +for key in DictD.keys.sort() { + print(key) +} + +for value in DictD.values.sort() { + print(value) +} + +let keys = [Int](DictD.keys) +print(keys) diff --git a/learn/AcePlay/AcePlay.playground/Pages/Closure.xcplaygroundpage/Contents.swift b/learn/AcePlay/AcePlay.playground/Pages/Closure.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..66a43a8 --- /dev/null +++ b/learn/AcePlay/AcePlay.playground/Pages/Closure.xcplaygroundpage/Contents.swift @@ -0,0 +1,130 @@ +//: [Previous](@previous) + +import UIKit + + +// +//闭包采取如下三种形式之一: +// 1. 全局函数是一个有名字但不会捕获任何值的闭包 +// 2. 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包 +// 3. 闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的匿名闭包 +// + +// +//Swift闭包语法特点: +// 1. 利用上下文推断参数和返回值类型 +// 2. 隐式返回单表达式闭包,即单表达式闭包可以省略return关键字 +// 3. 参数名称缩写 +// 4. 尾随(Trailing)闭包语法 +// + + +/* + The sort(_:) method accepts a closure that takes two arguments of the same type as the array’s contents, and returns a Bool value to say whether the first value should appear before or after the second value once the values are sorted. The sorting closure needs to return true if the first value should appear before the second value, and false otherwise. + + */ + +let company = ["Tencent", "Apple", "Facebook", "Google", "Twitter", "Amazon"] +var sortedCompany: [String] = [] + +printLine("Sort") +sortedCompany = company.sort() +print(sortedCompany) +sortedCompany = [] + +printLine("Sort With Function A") +func backwardsA(a: String, b: String) -> Bool { + return a > b +} +sortedCompany = company.sort(backwardsA) +print(sortedCompany) +sortedCompany = [] + +printLine("Sort With Backwards Closure A [Closure Expression Syntax]") +sortedCompany = company.sort({ (a: String, b: String) -> Bool in return a>b }) +print(sortedCompany) +sortedCompany = [] + +// 参数及返回类型自动推断 +printLine("Sort With Backwards Closure B [Inferring Type From Context]") +sortedCompany = company.sort({ a, b in return a > b }) +print(sortedCompany) +sortedCompany = [] + +// 隐式返回表达式闭包,省略return +printLine("Sort With Backwards Closure C [Implicit Returns from Single-Expression Closures]") +sortedCompany = company.sort({ a, b in a > b }) +print(sortedCompany) +sortedCompany = [] + +// 简写参数名 +printLine("Sort With Backwards Closure D [Shorthand Argument Names]") +sortedCompany = company.sort({ $0 > $1 }) +print(sortedCompany) +sortedCompany = [] + +/* + There’s actually an even shorter way to write the closure expression above. Swift’s String type defines its string-specific implementation of the greater-than operator (>) as a function that has two parameters of type String, and returns a value of type Bool. This exactly matches the function type needed by the sort(_:) method. Therefore, you can simply pass in the greater-than operator, and Swift will infer that you want to use its string-specific implementation: + */ +printLine("Sort With Backwards Closure E [Operator Functions]") +sortedCompany = company.sort(>) +print(sortedCompany) +sortedCompany = [] + +// Trailing Closure +printLine("Sort With Backwards Closure F [Trailing Closure]") +sortedCompany = company.sort() { a, b in a > b} // 如果闭包参数是这个函数的最后一个参数,是可以采用尾随闭包写法 +//sortedCompany = company.sort { a, b in a > b} // 如果闭包参数是这个函数的唯一一个参数,是可以不用写括号的 +print(sortedCompany) +sortedCompany = [] + + +let digitNames = [ + 0: "零", + 1: "壹", + 2: "贰", + 3: "叁", + 4: "肆", + 5: "伍", + 6: "陆", + 7: "柒", + 8: "捌", + 9: "玖", +] +let numbers = [9876543210, 1413, 110, 64] +// map函数可能不用指定参数类型,但要指定返回值类型 +let digitString = numbers.map() { + (digit) -> String in + var n = digit // 参数digit不能在函数体内被修改 + var s = "" + while n > 0 { + s = digitNames[n % 10]! + s + n /= 10 + } + return s +} + +print(digitString) + + +printLine("Captuare Value") + +// 捕获值 +func makeIncrementer(step:Int) -> () -> Int { + var total = 0 + func inc() -> Int { + total += step + return total + } + + return inc +} + +var closureFuncA = makeIncrementer(1) +print("ClosureFuncA:", closureFuncA()) +print("ClosureFuncA:", closureFuncA()) +var closureFuncB = closureFuncA +print("ClosureFunnB:", closureFuncB()) +var closureFuncC = makeIncrementer(1) +print("ClosureFuncC:", closureFuncC()) + diff --git a/learn/AcePlay/AcePlay.playground/Pages/Functions.xcplaygroundpage/Contents.swift b/learn/AcePlay/AcePlay.playground/Pages/Functions.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..ebcfc6e --- /dev/null +++ b/learn/AcePlay/AcePlay.playground/Pages/Functions.xcplaygroundpage/Contents.swift @@ -0,0 +1,56 @@ +//: [Previous](@previous) + +import Foundation + + +func Hello() -> Void { // func Hello() -> () { } + print("Hello Swift World") +} + + +printLine("Functions") + +Hello() + +printLine("Multiple Return Types") + +func minMax(data:Array) -> (min:Int, max:Int)? { + guard data.count > 0 else { + return nil + } + + var min = data[0] + var max = data[0] + + for i in 1.. data[i] ? data[i] : min + max = max < data[i] ? data[i] : max + } + + return (min, max) +} + +var Data: Array = [3, 8, 4, 1, 0, -2, 9, 6, 7] + +if let ret = minMax(Data) { + print("Min:", ret.min, " Max:", ret.max) +} + +// 外部参数包能相同, 但内部参数名不能相同 +func sameExternalParameterNames( ExName a: Int, ExName b: Int) -> Int { + return max(a, b) +} +print(sameExternalParameterNames(ExName: 10, ExName: 20)) + +// 引用传参 +func swapTwoInts(inout a: Int, inout _ b: Int) -> Void { + let t: Int = a + a = b + b = t +} + +var IntA = 10 +var IntB = 20 +swapTwoInts(&IntA, &IntB) + + diff --git a/learn/AcePlay/AcePlay.playground/Sources/Basic.swift b/learn/AcePlay/AcePlay.playground/Sources/Basic.swift deleted file mode 100644 index dddda1f..0000000 --- a/learn/AcePlay/AcePlay.playground/Sources/Basic.swift +++ /dev/null @@ -1,105 +0,0 @@ -import UIKit - -public -func SwiftBasics() -> Void { - let str = "Hello, playground.小狗:🐶 锤子:🔨" - - // Index - let strInx:String.Index = str.startIndex - strInx.successor() - print(strInx) - - for c in str.characters { - print(c, terminator: "") - } - print() - - // Print separator & terminator - var company:Array = [ "Apple", "Google", "Facebook", "Tencent" ] - print(company[0], company[1], company[2], company[3], separator: "#", terminator: " $$$$$\n") - - printLine("Count company Array 1") - for (i,v) in company.enumerate() { // enumerate 返回的是 index value 组成的元组 - print(i, v, separator: " - ", terminator: "\n") - } - - printLine("Count company Array 2") - company.insert("Alibaba", atIndex: company.count) - for i in 0..(0.. = [] - var SetB = Set() - var SetC: Set = ["ASM", "C", "C++", "go", "Swift"] - //var SetD: Set = ["mov", "pop", "push", "xchg"] // 可以通过数组类型推断出Set的类型 - SetB.insert("A") - SetB.insert("c") - SetB.insert("c") - SetB.count - //SetC.removeFirst() - SetC.remove("ASM") - - if let removedVal = SetC.remove("ASM") { - print("\(removedVal) I'm over it.") - } else { - print("I never much cared for that.") - SetC.insert("ASM") - } - - if SetC.contains("Swift") { - print("SetC Contains Swift") - } - - for v in SetC.sort() { - print(v) - } - - printLine("Dictionary") - //var DictA = Dictionary() - //var DictB = ["KA":"VA", "KB":"VB", "KC":"VC"] - //var DictC: [String:String] = [:] - var DictD = [Int:String]() - - DictD[1] = "V1" - DictD[4] = "V2" - DictD[99] = "V3" - DictD[36] = "F4" - if let oldValue = DictD.updateValue("V4", forKey: 36) { // means: if let oldValue = DictD[36] - print("The old value for Key:36 was \(oldValue)") - } - - print("DictD Item Count: ", DictD.count) - - for (k, v) in DictD { - print("Key:", k, " Value: ", v) - } - - for key in DictD.keys.sort() { - print(key) - } - - for value in DictD.values.sort() { - print(value) - } - - let keys = [Int](DictD.keys) - print(keys) -} diff --git a/learn/AcePlay/AcePlay.playground/Sources/Func.swift b/learn/AcePlay/AcePlay.playground/Sources/Func.swift deleted file mode 100644 index 344f9ab..0000000 --- a/learn/AcePlay/AcePlay.playground/Sources/Func.swift +++ /dev/null @@ -1,13 +0,0 @@ -//import Foundation -import UIKit - -func Hello() -> Void { - print("Hello Swift World") -} - - -public -func SwiftFunctions() -> Void { - printLine("Functions") - Hello() -} \ No newline at end of file diff --git a/learn/AcePlay/AcePlay.playground/contents.xcplayground b/learn/AcePlay/AcePlay.playground/contents.xcplayground index 5da2641..90f7190 100644 --- a/learn/AcePlay/AcePlay.playground/contents.xcplayground +++ b/learn/AcePlay/AcePlay.playground/contents.xcplayground @@ -1,4 +1,8 @@ - - + + + + + + \ No newline at end of file diff --git a/learn/AcePlay/AcePlay.playground/playground.xcworkspace/xcuserdata/Ace.xcuserdatad/UserInterfaceState.xcuserstate b/learn/AcePlay/AcePlay.playground/playground.xcworkspace/xcuserdata/Ace.xcuserdatad/UserInterfaceState.xcuserstate index 4665619d02c5e2c18e12d993b0cd6ba036aedea6..5f08ca2a96df821454713de6a53f5ff0e5314444 100644 GIT binary patch literal 13902 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 X(rVMD3%6Q?2;ZVy;XCw6yZXNX&!iIs -- 2.47.0