Functions and Closures
github:Swift基礎(chǔ)實(shí)例
github:SwiftBasicTableView
函數(shù)
- 函數(shù)聲明
用func聲明一個(gè)函數(shù),通過(guò)函數(shù)名來(lái)調(diào)用函數(shù),函數(shù)如果有參數(shù),在圓括號(hào)()中需要跟上相應(yīng)參數(shù)。用符號(hào)->把函數(shù)的參數(shù)和函數(shù)的返回值類型隔開(kāi)。
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ù)返回多個(gè)值
從函數(shù)返回多個(gè)值時(shí),可以使用元組tuple,通過(guò) 名字 或 索引來(lái)訪問(wèn)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ù)放在了一個(gè)數(shù)組
numbers中
- 函數(shù)嵌套
嵌套函數(shù)中,內(nèi)層函數(shù)可以使用外層函數(shù)中的變量。一個(gè)函數(shù)中的代碼如果太長(zhǎng),或者比較復(fù)雜,那么可以使用嵌套函數(shù)來(lái)組織組織這些代碼:
func returnFifteen() ->Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
print(returnFifteen())
- 返回函數(shù)
Swift的函數(shù)是第一類類型first-class type,這意味著一個(gè)函數(shù)可以把其他函數(shù)作為它的返回值:
func makeIncrementer() ->((Int)->Int) {
func addOne(number:Int) ->Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
print(increment(7))
- 在函數(shù)
makeIncrementer中,構(gòu)造了另外一個(gè)函數(shù)addOne并將其返回,返回函數(shù)名就可以(猜測(cè),可能返回的是函數(shù)指針)
- 函數(shù)作為參數(shù)
一個(gè)函數(shù)可以作為另外一個(gè)函數(shù)的參數(shù),傳遞進(jìn)去:
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ù)時(shí),也是只傳遞名稱就可以
閉包(block)
閉包格式
{ (參數(shù)) -> 返回值類型 in
statements
}```
- 有名稱的閉包
函數(shù)是特殊的閉包:代碼塊可以稍后被調(diào)用。上面的嵌套函數(shù),就屬于是有名字的閉包,無(wú)名的閉包(`匿名閉包`)是不寫(xiě)名字(比如`函數(shù)名`),然后把代碼放在大括號(hào)`{}`中。再看下面的栗子:假設(shè)我們要寫(xiě)兩個(gè)函數(shù),一個(gè)計(jì)算兩個(gè)數(shù)的平方的平均值,一個(gè)計(jì)算兩個(gè)數(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ù)。如果我們可以定義這樣一個(gè)函數(shù),這個(gè)函數(shù)以兩個(gè)數(shù)和一個(gè)使用這兩個(gè)數(shù)的函數(shù)作為參數(shù),來(lái)計(jì)算平均值而不是重復(fù)調(diào)用將會(huì)非常好,我們可以使用閉包作為函數(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. 無(wú)名稱閉包
下面說(shuō)一下無(wú)名內(nèi)聯(lián)閉包,代碼也是寫(xiě)在大括號(hào) `{}` 中,代碼用 `in` 將參數(shù)和返回類型與實(shí)現(xiàn)(`body`)隔開(kāi):
// 注意格式,每一行換行的地方
individualScores.map({
(number:Int) ->Int in
let result = number+3
return result
})
3. 閉包簡(jiǎn)寫(xiě)
如果閉包的類型是已知的,比如 `delegate`,那么可以刪掉閉包的`參數(shù)類型`或`返回類型`,或者兩者都刪掉。單語(yǔ)句閉包隱式返回這條語(yǔ)句的執(zhí)行結(jié)果.
individualScores.map({
number in number+3})
print(individualScores)
let mappedScores = individualScores.map({
number in number+3})
- 數(shù)組 `individualScores` 中的值沒(méi)有變化,而是調(diào)用 `.map` 之后會(huì)返回一個(gè)新的數(shù)組,新數(shù)組`mappedScores`中的值會(huì)每個(gè)都加3
我們還可以忽略參數(shù)名,使用默認(rèn)參數(shù)名`$0`,如果有多個(gè)參數(shù),使用 `$n` 作為第 `n-1` 個(gè)參數(shù):
individualScores.map({
$0+3})
如果某一個(gè)函數(shù)的最后一個(gè)參數(shù)是閉包,那么這個(gè)閉包可以直接出現(xiàn)在圓括號(hào)`()`之后,例如下面的升序排序:
let sortedNumbers = individualScores.sort(){
$0 < $1
}
print(sortedNumbers)
如果某一個(gè)函數(shù)唯一的參數(shù)是閉包,那么可以把圓括號(hào)`()`省略掉:
let sortedNumbers = individualScores.sort {
$0 < $1
}
print(sortedNumbers)
4. 總結(jié)
>閉包是函數(shù)的一種,但閉包的真正意義是:把參數(shù)傳遞進(jìn)一個(gè)塊(這個(gè)塊是用來(lái)實(shí)現(xiàn)閉包的),然后對(duì)參數(shù)就行修改,修改過(guò)之后,再使用??偨Y(jié)為一句話,傳遞參數(shù)-->修改-->使用