import Foundation數組
//1.函數的定義與調用
//以 func 做爲前綴,返回箭頭 -> 表示函數的返回類型
func sayHello(name: String) -> String {
let greeting = "Hello " + name + "!"
return greeting
}閉包
println(sayHello("Anna"))函數
//1.1函數的參數與返回值
//函數能夠有多個輸入參數,寫在圓括號中,用逗號分隔
func minusResult(start: Int, end: Int) -> Int{
return end - start
}ui
println(minusResult(1, 10))spa
//1.2無參函數
func sayHelloWorld() -> String {
return "hello world"
}
println(sayHelloWorld())指針
//1.3無返回值函數
/*
嚴格上來講,雖然沒有定義返回值,sayGoodbye 函數依然返回了值。
沒有定義返回類型的函數會返回特殊的值,叫 Void。它實際上是一個空的元組(tuple),沒有任何元素,能夠寫成()。
*/
func sayGoodbye(name: String) {
println("Goodbye, \(name)" )
}
println(sayGoodbye("Dave"))對象
//1.4多重返回值函數
//你能夠用元組(tuple)類型讓多個值做爲一個複合值從函數中返回
func count(string : String) -> (vs: Int, cs: Int, os: Int) {
var vowels = 0, consonants = 0, others = 0
for character in string {
switch String(character).lowercaseString {
case "a", "e", "i", "o", "u":
++vowels
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
++consonants
default:
++others
}
}
return (vowels, consonants, others)
}
let total = count("some arbitrary string!")
println("\(total.vs) vowels and \(total.cs) consonants")排序
//2 函數參數名
//2.1 外部參數名rem
//Demo:把兩個字符串聯在一塊兒,演示使用外部參數的好處
/*
//不使用外部參數
func join(s1: String, s2: String, joiner: String) -> String {
return s1 + joiner + s2
}
println(join("hello", "world", ", ")) //這三個字符串的用途不是很明確
*/字符串
/*
//使用外部參數名稱
//爲了讓這些字符串的用途更爲明顯,咱們爲 join 函數添加外部參數名
func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String {
return s1 + joiner + s2
}
//使用外部參數名更有表現力,更爲通順,同時還保持了函數體是可讀的和有明確意圖的
println(join(string: "hello", toString: "world", withJoiner : ", "))
*/
//2.2 簡寫外部參數名
//若是你須要提供外部參數名,可是局部參數名已經定義好了,那麼你不須要寫兩次這些參數名。相反,只寫一次參數名,並用井號(#)做爲前綴就能夠了。這告訴 Swift 使用這個參數名做爲局部和外部參數名。
func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
for character in string {
if character == characterToFind {
return true
}
}
return false
}
//這樣定義參數名,使得函數體更爲可讀,清晰,同時也能夠以一個不含糊的方式被調用
let containsAVee = containsCharacter(string: "qwertyuiop", characterToFind: "y")
println(containsAVee)
//2.3 默認參數值
//你能夠在函數體中爲每一個參數定義默認值。當默認值被定義後,調用這個函數時能夠略去這個參數
func join(string s1: String, toString s2: String, withJoiner joiner: String = ", ") -> String {
return s1 + joiner + s2
}
let str1 = join(string: "hello", toString: "world", withJoiner: "-") //指定第三個參數
println(str1)
let str2 = join(string: "hello", toString: "world") //不指定第三個參數, 第三個參數將使用默認值
println(str2)
//2.4 默認值參數的外部參數名
//當你未給 帶默認值的參數提供外部參數名時,Swift 會自動提供外部名字。此時外部參數名與局部名字是同樣的,就像你已經在局部參數名前寫了井號(#)同樣
func join(s1: String, s2: String, joiner: String = " ") -> String {
return s1 + joiner + s2
}
let str3 = join("hello", "world", joiner: "-")
println(str3)
//3.可變參數
//傳入可變參數的值在函數體內當作這個類型的一個數組。例如,一個叫作 numbers 的 Double... 型可變參數,在函數體內能夠當作一個叫 numbers 的 Double[] 型的數組常量。
//一個函數最多能有一個可變參數
//可變參數必須放在參數表中最後的位置
func aritheticMean(numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
println(aritheticMean(1.2, 3.5, 4.6))
println(aritheticMean(1.2, 3.5, 4.6, 9.0, 10.0))
//4 常量參數與變量參數
//函數參數默認是常量。可是有時候,若是函數中傳入的參數能夠修改的話將頗有用。你能夠經過指定一個或多個參數爲變量參數,從而避免本身在函數中定義新的變量。變量參數不是常量,你能夠在函數中把它當作新的可修改副原本使用。
//經過在參數名前加關鍵字 var 來定義變量參數
func alignRight(var string: String, count: Int, pad: Character) -> String {
let amountToPad = count - countElements(string)
for _ in 1...amountToPad {
string = pad + string
}
return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
println("originalString:" + originalString)
println("paddedString:" + paddedString)
//5 輸入輸出參數
//變量參數,正如上面所述,僅僅能在函數體內被更改。若是你想要一個函數能夠修改參數的值,而且想要 這些修改在函數調用結束後仍然存在,那麼就應該把這個參數定義爲輸入輸出參數(In-Out Parameters)。
//定義一個輸入輸出參數,在參數的前面加 inout關鍵字
//輸入輸出參數不能有默認值,並且可變參數不能用 inout 標記。若是你用 inout 標記一個參數,這個參數不能被 var 或者 let 標記。
func swapTwoInts(inout a: Int, inout b:Int) {
let temp = a
a = b
b = temp
}
//只能傳入一個變量做爲輸入輸出參數
var someInt = 3
var anotherInt = 7
//當傳入的參數做爲輸入輸出參數時,須要在參數的前面加&,表示這個值能夠被函數修改
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
//6.函數類型 (是一種數據類型, 相似C語言的函數指針, OC語言的Block)
//分三步: 1.定義函數; 2.聲明函數類型變量或常量; 3.給函數類型變量賦值
//1.定義函數
func addTwoInts(a: Int, b: Int) -> Int {
return a + b
}
func sum(a: Int, b: Int) -> Int {
return a - b
}
func printHelloWorld()
{
println("hello, world")
}
/*
//二、聲明一個叫作 mathFunction 的變量,類型是'一個有兩個 Int 型的參數並返回一個 Int 型的值的函數'
var mathFunction: (Int, Int) -> Int
//3.給函數類型變量賦值
mathFunction = addTwoInts
//既然是變量, 咱們能夠從新給mathFunction賦值
mathFunction = sum
*/
/*
//2 3步合併
var mathFunction: (Int, Int) -> Int = sum
*/
//類型推導, 可讓Swift來推測 mathFunction 的類型
var mathFunction = sum
//mathFunction = printHelloWorld //錯誤, 類型不匹配
//4.使用
println("Result: \(mathFunction(2, 3))")
//Swift調用C函數
desc1()
//Swift調用OC
var funcClass = FuncBlock() //拿到OC類對象
funcClass.desc2()
//6.1 函數類型做爲參數類型
func printMathResult(mathFun: (Int, Int) -> Int, a: Int, b: Int){
println("Result: \(mathFun(a, b))")
}
printMathResult(addTwoInts, 4, 7)
/*
//6.2 函數類型做爲返回類型
func stepForward(input: Int) -> Int {
return input + 1
}
func stepBackward(input: Int) -> Int {
println("stepBackward")
return input - 1
}
//好,有沒有暈?😄暈了就休息一下,再看一遍剛剛講過的內容;沒暈就繼續了
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
return backwards ? stepBackward : stepForward //返回函數類型
}
var currentValue = 3
let moveNearerTozero = chooseStepFunction(currentValue > 0)
//let moveNearerTozero:(Int) -> Int = chooseStepFunction(true) //原型
//moveNearerTozero = stepBackward
println("moveNearerTozero:\(moveNearerTozero)") //moveNearerTozero指向stepBackward
println("Result:\(moveNearerTozero(10))")
*/
//嵌套函數
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int {
return input + 1
}
func stepBackward(input: Int) -> Int {
println("stepBackward")
return input - 1
}
return backwards ? stepBackward : stepForward //返回函數類型
}
var currentValue = -4
let moveNearerTozero = chooseStepFunction(currentValue > 0)
println("嵌套函數: \(moveNearerTozero(10))")
//8.閉包
//8.1閉包表達式
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
//不使用閉包
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
//Swift 標準庫提供了sort函數,會根據您提供的基於輸出類型排序的閉包函數將已知類型數組中的值進行排序。
var reversed = sort(names, backwards)
println(reversed)
//使用閉包
//閉包的函數體部分由關鍵字in引入。 該關鍵字表示閉包的參數和返回值類型定義已經完成,閉包函數體即將開始。
reversed = sort(names, {(s1: String, s2: String) -> Bool in
return s1 > s2
})
//根據上下文推斷類型
reversed = sort(names, {s1, s2 in return s1 > s2})
//8.2單表達式閉包隱式返回
//若是閉包體只有一個表達式, 那麼return關鍵字能夠省略
reversed = sort(names, {s1, s2 in s1 > s2})
//8.3 參數名稱縮寫
//$0和$1表示閉包中第一個和第二個String類型的參數。
reversed = sort(names, {$0 > $1})
//8.4 運算符函數
//Swift 的String類型定義了關於大於號 (>) 的字符串實現
reversed = sort(names, >)
//8.5 尾隨閉包
//若是您須要將一個很長的閉包表達式(以致於不能在一行中進行書寫時)做爲最後一個參數傳遞給函數,可使用尾隨閉包來加強函數的可讀性。 尾隨閉包是一個書寫在函數括號以後的閉包表達式,函數支持將其做爲最後一個參數調用。
reversed = sort(names){$0 > $1}
println(reversed)
//8.6 捕獲值
func makeIncrementor(forIncrement amount: Int) -> ()->Int {
var runningTotal = 0
//incrementor函數並無獲取任何參數,可是在函數體內訪問了runningTotal和amount變量。這是由於其經過捕獲在包含它的函數體內已經存在的runningTotal和amount變量而實現
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
let incrementByTen = makeIncrementor(forIncrement: 10)
//由於每次調用該函數的時候都會修改runningTotal的值,incrementor捕獲了當前runningTotal變量的引用,而不 是僅僅複製該變量的初始值。捕獲一個引用保證了當makeIncrementor結束時候並不會消失,也保證了當下一次執行incrementor函數 時,runningTotal能夠繼續增長
println(incrementByTen()) //10
println(incrementByTen()) //20
println(incrementByTen()) //30
let incrementBySeven = makeIncrementor(forIncrement: 7)
println(incrementBySeven()) //7
println(incrementByTen()) //40
//8.7 閉包是引用類型
//上面的例子中,incrementBySeven和incrementByTen是常量,可是這些常量指向的閉包仍然能夠增長其捕獲的變量值。 這是由於函數和閉包都是引用類型。
//若是將閉包賦值給了兩個不一樣的常量/變量,兩個值都會指向同一個閉包,指向的都是 incrementorlet alsoIncrementByTen = incrementByTenprintln(alsoIncrementByTen()) //50