Functions and Closures
github:Swift基礎實例
github:SwiftBasicTableView
函數(shù)
- 函數(shù)聲明
用func
聲明一個函數(shù)逗概,通過函數(shù)名來調(diào)用函數(shù)召衔,函數(shù)如果有參數(shù)修肠,在圓括號()
中需要跟上相應參數(shù)围段。用符號->
把函數(shù)的參數(shù)和函數(shù)的返回值類型隔開。
var nameAndDay = ""
func greet(name: String, day: String, number: Int) ->String {
return "Hello \(name), today is \(day), \(number)."
}
nameAndDay = greet("Swift", day: "Sunday", number: 1)
print(nameAndDay)
- 輸出
Hello Swift, today is Sunday, 1.
- 函數(shù)返回多個值
從函數(shù)返回多個值時合愈,可以使用元組tuple
照捡,通過 名字 或 索引來訪問tuple
中的值:
func calculate(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
var min = scores[0]
var max = scores[0]
var sum = 0
for score in scores {
if score > max {
max = score
}
else if score < min {
min = score
}
sum += score
}
return (min,max,sum)
}
let statistics = calculate([5, 10, 39, 5])
print(statistics.sum)
print(statistics.1)
- 參數(shù)數(shù)量可變的函數(shù)
func sumOf(numbers:Int...) ->Int {
var sum = 0
// numbers.count
for number in numbers {
sum += number
}
return sum
}
print(sumOf())
print(sumOf(1,3,4,5))
- 上面代碼中颅湘,一系列的參數(shù)放在了一個數(shù)組
numbers
中
- 函數(shù)嵌套
嵌套函數(shù)中,內(nèi)層函數(shù)可以使用外層函數(shù)中的變量栗精。一個函數(shù)中的代碼如果太長闯参,或者比較復雜,那么可以使用嵌套函數(shù)來組織組織這些代碼:
func returnFifteen() ->Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
print(returnFifteen())
- 返回函數(shù)
Swift
的函數(shù)是第一類類型first-class type
悲立,這意味著一個函數(shù)可以把其他函數(shù)作為它的返回值:
func makeIncrementer() ->((Int)->Int) {
func addOne(number:Int) ->Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
print(increment(7))
- 在函數(shù)
makeIncrementer
中鹿寨,構造了另外一個函數(shù)addOne
并將其返回,返回函數(shù)名就可以(猜測薪夕,可能返回的是函數(shù)指針)
- 函數(shù)作為參數(shù)
一個函數(shù)可以作為另外一個函數(shù)的參數(shù)脚草,傳遞進去:
func lessThanTen(number:Int) ->Bool {
return number < 10
}
func hasAnyMatches(list:[Int], condition:(Int) ->Bool) ->Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
var numbers = [20,13,4,9]
hasAnyMatches(numbers, condition: lessThanTen)
- 傳遞函數(shù)時,也是只傳遞名稱就可以
閉包(block)
閉包格式
{ (參數(shù)) -> 返回值類型 in
statements
}```
- 有名稱的閉包
函數(shù)是特殊的閉包:代碼塊可以稍后被調(diào)用原献。上面的嵌套函數(shù)馏慨,就屬于是有名字的閉包埂淮,無名的閉包(`匿名閉包`)是不寫名字(比如`函數(shù)名`),然后把代碼放在大括號`{}`中写隶。再看下面的栗子:假設我們要寫兩個函數(shù)倔撞,一個計算兩個數(shù)的平方的平均值,一個計算兩個數(shù)的立方的平均值慕趴,一般做法是:
func square(a:Float) ->Float {
return aa
}
func cube(a:Float) ->Float {
return aa*a
}
func averageSumOfSquare(a:Float, b:Float) ->Float {
return (square(a) + square(b))/2.0
}
func averageSumOfCube(a:Float, b:Float) ->Float {
return (cube(a) + cube(b)) / 2.0
}
averageSumOfSquare(1.0, b: 3.0)
averageSumOfCube(2.0, b: 3.0)
上面函數(shù) `averageSumOfSquare` 和 `averageSumOfCube` 唯一不同之處就是分別調(diào)用了平方函數(shù)和立方函數(shù)痪蝇。如果我們可以定義這樣一個函數(shù),這個函數(shù)以兩個數(shù)和一個使用這兩個數(shù)的函數(shù)作為參數(shù)冕房,來計算平均值而不是重復調(diào)用將會非常好霹俺,我們可以使用閉包作為函數(shù)參數(shù):
func averageOfSum(a:Float, b:Float, f:(Float ->Float)) ->Float {
return (f(a) + f(b))/2.0
}
averageOfSum(2.0, b: 3.0, f: square)
averageOfSum(3.0, b: 3.0, f: cube)
- `square`和`cube`可以被看做有名稱的閉包
2. 無名稱閉包
下面說一下無名內(nèi)聯(lián)閉包,代碼也是寫在大括號 `{}` 中毒费,代碼用 `in` 將參數(shù)和返回類型與實現(xiàn)(`body`)隔開:
// 注意格式,每一行換行的地方
individualScores.map({
(number:Int) ->Int in
let result = number+3
return result
})
3. 閉包簡寫
如果閉包的類型是已知的愈魏,比如 `delegate`觅玻,那么可以刪掉閉包的`參數(shù)類型`或`返回類型`,或者兩者都刪掉培漏。單語句閉包隱式返回這條語句的執(zhí)行結(jié)果.
individualScores.map({
number in number+3})
print(individualScores)
let mappedScores = individualScores.map({
number in number+3})
- 數(shù)組 `individualScores` 中的值沒有變化溪厘,而是調(diào)用 `.map` 之后會返回一個新的數(shù)組,新數(shù)組`mappedScores`中的值會每個都加3
我們還可以忽略參數(shù)名牌柄,使用默認參數(shù)名`$0`畸悬,如果有多個參數(shù),使用 `$n` 作為第 `n-1` 個參數(shù):
individualScores.map({
$0+3})
如果某一個函數(shù)的最后一個參數(shù)是閉包珊佣,那么這個閉包可以直接出現(xiàn)在圓括號`()`之后蹋宦,例如下面的升序排序:
let sortedNumbers = individualScores.sort(){
$0 < $1
}
print(sortedNumbers)
如果某一個函數(shù)唯一的參數(shù)是閉包,那么可以把圓括號`()`省略掉:
let sortedNumbers = individualScores.sort {
$0 < $1
}
print(sortedNumbers)
4. 總結(jié)
>閉包是函數(shù)的一種咒锻,但閉包的真正意義是:把參數(shù)傳遞進一個塊(這個塊是用來實現(xiàn)閉包的)冷冗,然后對參數(shù)就行修改,修改過之后惑艇,再使用蒿辙。總結(jié)為一句話滨巴,傳遞參數(shù)-->修改-->使用