iOS學習筆記42-Swift(二)函數(shù)和閉包

上一節(jié)我們講了Swift的基礎部分号涯,例如數(shù)據(jù)類型、運算符和控制流等孝偎,現(xiàn)在我們來看下Swift的函數(shù)和閉包

一映皆、Swift函數(shù)

函數(shù)是一個完成獨立任務的代碼塊挤聘,Swift中的函數(shù)不僅可以像C語言中的函數(shù)一樣作為函數(shù)的參數(shù)和返回值,而且還支持嵌套捅彻,支持函數(shù)參數(shù)默認值组去、可變參數(shù)等。

/**
* 1步淹、函數(shù)第一個參數(shù)默認沒有外部參數(shù)名从隆,其他參數(shù)默認有
* 2、可變參數(shù)只能在最后一個參數(shù)缭裆,可變參數(shù)的類型是數(shù)組
* 3键闺、返回類型也可以是元組
* 4、可以在參數(shù)前面加inout關鍵字幼驶,表示內部修改會改變外部的變量,調用時要加“&”符號
* 5韧衣、Swift中的函數(shù)本身也可以看做一種類型盅藻,既可以作為參數(shù)又可以作為返回值。
     例如 var fun:(Int,Int)->(Double,Int) = fun2
*/
func 函數(shù)名(參數(shù)1:類型1, inout 參數(shù)2:類型2=默認值2, 可變參數(shù)3:類型3...) -> 返回值類型 {

    函數(shù)體

    return 返回值
}
函數(shù)實例:
1. 普通函數(shù)
//1. 定義一個函數(shù)畅铭,注意參數(shù)和返回值氏淑,如果沒有返回值可以不寫返回值或者寫成Void、空元組()
func mySum(num1:Int, num2:Int) -> Int{
    return num1 + num2
}
//調用函數(shù)硕噩,num2是外部參數(shù)名假残,函數(shù)第一個參數(shù)默認沒有外部參數(shù)名,其他參數(shù)默認有
mySum(1, num2: 2)
2. 設置外部參數(shù)名
/**
*  2. 函數(shù)參數(shù)名分為局部參數(shù)名和外部參數(shù)名
*/
func mySplit(string a:String, seperator b:Character) -> [String]{
    return ["hello", "world", "!"]
}
/* 
由于給mySplit函數(shù)設置了外部參數(shù)名string和seperator,所以執(zhí)行的時候必須帶上外部參數(shù)名辉懒,
此處可以看到一個有意義的外部參數(shù)名大大節(jié)省開發(fā)者使用成本
 */
mySplit(string: "hello,world,!", seperator: ",") //結果:["hello", "world", "!"]
3. 設置默認參數(shù)值
//3. 設置函數(shù)的最后一個參數(shù)默認值設置為",",注意如果使用默認參數(shù)那么此參數(shù)名將默認作為外部參數(shù)名
func mySplit3(string:String, seperator:Character=",")->[String]{
    return ["hello", "world", "!"]
}
mySplit3("hello,world,!") //結果:["hello", "world", "!"]
mySplit3("hello world !", seperator: " ") //結果:["hello", "world", "!"]
4. 設置可變參數(shù)
/**
 * 4. 可變參數(shù),一個函數(shù)最多有一個可變參數(shù)并且作為最后一個參數(shù)
 * 下面strings參數(shù)在內部是一個[String]阳惹,對于外部是不定個數(shù)的String參數(shù)
 */
func myJoinStr(seperator seperator:Character=",", strings:String...) -> String{
    var result:String = ""
    for var i = 0;i < strings.count; ++i{
        if i != 0{
            result.append(seperator)
        }
        result += strings[i]
    }
    return result
}
//調用
myJoinStr(seperator:" ", strings: "hello","world","!") //結果:"hello world !"
5. 設置輸入輸出參數(shù)
/**
 *  5. 輸入輸出參數(shù)
 *  通過輸入輸出參數(shù)可以在函數(shù)內部修改函數(shù)外部的變量(注意調用時不能是常量或字面量)
 *  注意:下面的mySwap僅僅為了演示,實際使用時請用Swift的全局函數(shù)swap
 */
func mySwap(inout a:Int ,inout b:Int){
    a = a + b
    b = a - b
    a = a - b
}
var a = 1,b = 2
mySwap(&a, b: &b) //調用時參數(shù)加上“&”符號
print("a=\(a),b=\(b)") //結果:"a=2,b=1"
6. 函數(shù)類型使用
/**
 * 6. 函數(shù)類型
 */
var sum3 = mySum //自動推斷sum3的類型:(Int,Int)->Int,注意不同的函數(shù)類型之間不能直接賦值
sum3(1,num2: 2) //結果:3

//函數(shù)作為返回值
func fn() -> (Int,Int)->Int{
    //下面的函數(shù)是一個嵌套函數(shù)眶俩,作用于是在fn函數(shù)內部
    func minus(a:Int, b:Int) -> Int{
        return a - b
    }
    return minus;
}
var minus = fn()
minus(1,2) //結果:-1

//函數(shù)作為參數(shù)
func caculate(num1:Int,num2:Int,fn:(Int,Int)->Int) -> Int{
    return fn(num1,num2)
}
caculate(1,num2: 2,fn: mySum) //結果:3
caculate(1,num2: 2,fn: minus) //結果:-1

二莹汤、閉包

Swift中的閉包其實就是一個函數(shù)代碼塊,它和ObjC中的Block及Java中的lambda是類似的颠印。
閉包的特點就是可以捕獲和存儲上下文中的常量或者變量的引用纲岭,即使這些常量或者變量在原作用域已經(jīng)被銷毀了在代碼塊中仍然可以使用。

在Swift中閉包表達式的定義形式如下:
{ ( parameters ) -> returnType in 
    statements;
}
閉包使用:
1. 不使用閉包线罕,使用函數(shù)
func mySum(num1:Int,num2:Int) -> Int{
    return num1 + num2
}
func myMinus(num1:Int,num2:Int) -> Int{
    return num1 - num2
}
func myCaculate(num1:Int, num2:Int, fn:(Int,Int)->Int) -> Int{
    return fn(num1,num2)
}
var (a, b) = (1, 2)
myCaculate(a, num2: b, fn: mySum) //結果:3
myCaculate(a, num2: b, fn: myMinus) //結果:-1
2. 使用閉包
//利用閉包表達式替代函數(shù)mySum
myCaculate(a, num2: b, fn: {(num1:Int, num2:Int) -> Int in
    return num1 + num2
}) //結果:3
//利用閉包表達式替代函數(shù)myMinus
myCaculate(a, num2: b, fn: {(num1:Int, num2:Int) -> Int in
    return num1 - num2
}) //結果:-1
3. 閉包的簡化形式
//簡化形式,根據(jù)上下文推斷類型并且對于單表達式閉包(只有一個語句)可以隱藏return關鍵字
myCaculate(a, num2: b, fn: { num1, num2 in
    num1 + num2
}) //結果:3
myCaculate(a, num2: b, fn: { num1, num2 in
    num1 - num2
}) //結果:-1
4. 閉包繼續(xù)簡化止潮,使用參數(shù)縮寫
//再次簡化,使用參數(shù)名縮寫,使用$0...$n代表第n個參數(shù)钞楼,并且此in關鍵字也省略了
myCaculate(a, num2: b, fn: { $0 + $1 }) //結果:3
myCaculate(a, num2: b, fn: { $0 - $1 }) //結果:-1

考慮到閉包表達式的可讀取性喇闸,Swift中如果一個函數(shù)的最后一個參數(shù)是一個函數(shù)類型的參數(shù)(或者說是閉包表達式),則可以將此參數(shù)寫在函數(shù)括號之后窿凤,這種閉包稱之為“尾隨閉包”仅偎。

5. 尾隨閉包
//尾隨閉包
myCaculate(a,num2: b) { 
    $0 + $1
} //結果:3
myCaculate(a,num2: b) { 
    $0 - $1 
} //結果:-1
6. 捕獲變量

前面說過閉包之所以稱之為“閉包”,就是因為其可以捕獲一定作用域內的常量或者變量進而閉合并包裹著雳殊。

func myAdd() -> ()->Int {
    var total = 0
    var step = 1
    func fn() -> Int{
        total += step
        return total
    }
    return fn
}
/* 
fn捕獲了total和step橘沥,盡管下面的myAdd()執(zhí)行完后total和step被釋放,
但是由于fn捕獲了二者的副本夯秃,所以fn會隨著兩個變量的副本一起被存儲
 */
var a = myAdd()
a() //結果:1
a() //結果:2座咆,說明a中保存了total的副本(否則結果會是1)
 
var b = myAdd()
b() //結果:1,說明a和b單獨保存了total的副本(否則結果會是3)
 
var c = b
c() //結果:2仓洼,說明閉包是引用類型介陶,換句話說函數(shù)是引用類型(否則結果會是1)
  • Swift會自動決定捕獲變量或者常量副本的拷貝類型(值拷貝或者引用拷貝)而不需要開發(fā)者關心
  • 被捕獲的變量或者常量的內存管理同樣是由Swift來管理,我們不用關心色建,例如當上面的函數(shù)a不再使用了哺呜,那么fn捕獲的兩個變量也就釋放了。
有什么問題在下方評論區(qū)中提出箕戳!O(∩_∩)O哈某残!
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市陵吸,隨后出現(xiàn)的幾起案子玻墅,更是在濱河造成了極大的恐慌,老刑警劉巖壮虫,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件澳厢,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機剩拢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門线得,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人裸扶,你說我怎么就攤上這事框都。” “怎么了呵晨?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵魏保,是天一觀的道長。 經(jīng)常有香客問我摸屠,道長谓罗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任季二,我火速辦了婚禮檩咱,結果婚禮上,老公的妹妹穿的比我還像新娘胯舷。我一直安慰自己刻蚯,他們只是感情好,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布桑嘶。 她就那樣靜靜地躺著炊汹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逃顶。 梳的紋絲不亂的頭發(fā)上讨便,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機與錄音以政,去河邊找鬼霸褒。 笑死,一個胖子當著我的面吹牛盈蛮,可吹牛的內容都是我干的废菱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼抖誉,長吁一口氣:“原來是場噩夢啊……” “哼殊轴!你這毒婦竟也來了?” 一聲冷哼從身側響起寸五,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤梳凛,失蹤者是張志新(化名)和其女友劉穎耿币,沒想到半個月后梳杏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年十性,在試婚紗的時候發(fā)現(xiàn)自己被綠了叛溢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡劲适,死狀恐怖楷掉,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情霞势,我是刑警寧澤烹植,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站愕贡,受9級特大地震影響草雕,放射性物質發(fā)生泄漏。R本人自食惡果不足惜固以,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一墩虹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧憨琳,春花似錦诫钓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至闲擦,卻和暖如春慢味,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背墅冷。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工纯路, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寞忿。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓驰唬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腔彰。 傳聞我的和親對象是個殘疾皇子叫编,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內容