亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Swift > 正文

詳解Swift中的函數及函數閉包使用

2020-03-09 17:48:28
字體:
來源:轉載
供稿:網友

一、引言

函數是有特定功能的代碼段,函數會有一個特定的名稱調用時來使用。Swift提供了十分靈活的方式來創建與調用函數。事實上在Swift,每個函數都是一種類型,這種類型由參數和返回值來決定。Swift和Objective-C的一大區別就在于Swift中的函數可以進行嵌套。

而Swift中的閉包是有一定功能的代碼塊,這十分類似于Objective-C中的block語法。Swift中的閉包語法風格十分簡潔,其作用和函數的作用相似。

二、函數的創建與調用

函數通過函數名,參數和返回值來定義,參數和返回值決定一個函數的類型,在調用函數時,使用函數名來進行調用,示例如下:

//傳入一個名字 打印并將其返回func printName(name:String) -> String {  print(name)  return name}//進行函數的調用printName("HS")

也可以創建沒有參數的函數:

func onePuseTwo()->Int {  return 1+2}onePuseTwo()同樣也可以創建沒有返回值的函數:func sayHello(){  print("Hello")}sayHello()

上面介紹的函數類型都比較常見,對于多返回值的函數,在Objective-C中十分難處理,開發者通常會采用字典、數組等集合方式或者干脆使用block回調,在Swift中,可以使用元組作為函數的返回值,示例如下:

func tuples()->(Int,String){  return (1,"1")}tuples()

也可以是函數返回一個Optional類型的值,支持返回nil,示例如下:

func func1(param:Int)->Int? {  guard(param>0)else{    return nil  }  return param}func1(0)func1(1)

在函數的參數名前,開發者還可以再為其添加一個參數名稱作為外部參數名,示例如下:

func func1(count param:Int ,count2 param2:Int)->Int? {  //內部依然使用param  guard(param>0)else{    return nil  }  return param}//外部調用使用countfunc1(count: 0,count2: 0)func1(count: 1,count2: 1)

其實Swift函數中的參數列表有這樣一個特點,除了第一個參數外,之后的參數都默認添加一個一個和內部名稱相同的外部名稱,如果開發者不想使用這個外部名稱,使用_符號設置,示例如下:

func func2(param:Int,param2:Int,param3:Int) {  }//有外部名稱func2(0, param2: 0, param3: 0)func func3(param:Int,_ param2:Int,_ param3:Int) {  }//沒有外部名稱func3(0, 0, 0)

Swift也支持開發者為函數的參數創建一個默認值,如果函數的某個參數有設置默認值,則開發者在調用時可以省略此參數,示例如下:

func func4(param:Int=1,param2:Int=2,param3:Int) {  print(param,param2,param3)}func4(3,param3:3)

還有一種情形在Objective-C中也很處理,對于參數數量不定的函數,在前面章節介紹過,Objective-C一般會使用list指針來完成,在Swift中編寫這樣的函數十分簡單,示例如下:

func func5(param:Int...) {  for index in param {    print(index)  }}func5(1,2,3,4)

Swift中參數默認是常量,在函數中是不能修改外部傳入參數的值得,如果有需求,需要將參數聲明成inout類型,示例如下:

func func6(inout param:Int) {  param = 10}var count = 1//實際上傳入的是參數地址func6(&count)print(count)

三、函數類型

函數是一種特殊的數據類型,每一個函數屬于一種數據類型,示例如下:

func func7(a:Int,_ b:Int)->Int{  return a+b}var addFunc:(Int,Int)->Int = func7addFunc(1,2)

函數也可以作為參數傳入另一個函數,這十分類似于Objective-C中的block語法,示例如下:

func func7(a:Int,_ b:Int)->Int{  return a+b}var addFunc:(Int,Int)->Int = func7addFunc(1,2)func func8(param:Int,param2:Int,param3:(Int,Int)->Int) -> Int {  return param3(param,param2)}//傳入函數func8(1, param2: 2, param3: addFunc)//閉包的方式func8(2, param2: 2, param3:{ (a:Int,b:Int) -> Int in  return a*b  })

一個人函數也可以作為另一個函數的返回值,示例如下:

func func9()->(Int)->Int{  //Swift支持嵌套函數  func tmp(a:Int)->Int{    return a*a  }  return tmp}var myFunc = func9()myFunc(3)

四、從一個系統函數看閉包

Swift標準函數庫中提供了一個sort排序函數,對于已經元素類型的數組,調用sort函數會進行重新排序并返回新的排序后的數組。這個sort函數可以接收一個返回值為Bool類型的閉包,來確定第一個元素是否排在第二個元素前面。代碼示例如下:

var array = [3,21,5,2,64]func func1(param1:Int,param2:Int) -> Bool {  return param1>param2}//通過傳入函數的方式//array = [64,21,5,3,2]array = array.sort(func1)//通過閉包的方式//array = [2,3,5,21,64]array = array.sort({(param:Int,param2:Int)->Bool in            return param<param2          })

Swift語言有一個很顯著的特點就是簡潔,可以通過上下文推斷出類型的情況一般開發都可以將類型的書寫省略,這也是Swift語言設計的一個思路,由于閉包是作為函數的參數傳入函數中的,因為函數參數的類型是確定,因此閉包的類型是可以被編譯器推斷出來的,開發者也可以將閉包的參數類型和返回值省略,上面的代碼可以簡寫如下:

//將閉包的參數類型和返回值都省略array = array.sort({(p1,p2) in return p1>p2})

實際上,如果閉包中的函數體只有一行代碼,可以將return關鍵字也省略,這時會隱式的返回此行代碼的值,如下:

array = array.sort({(p1,p2) in  p1>p2})

看到上面的表達式,是不是有點小震驚,閉包表達式竟然可以簡寫成這樣!然而,你還是小看的Swift開發團隊,后面的語法規則會讓你明白什么是簡潔的極致??梢钥吹缴厦娴拇a實現還是有3部分:參數和返回值,閉包關鍵字,函數體。參數和返回值即是參數列表,p1,p2,雖然省略了參數類型和返回值類型,但這部分的模塊還在,閉包關鍵字即是in,它用來表示下面將是閉包的函數體,p1>p2即是函數體,只是這里省略了return關鍵字。閉包中既然參數類型和返回值類型編譯器都可以自己推斷出來,那么參數的數量編輯器也是可以自行推斷的,因此,參數列表實際上也是多余的,閉包中會自動生成一些參數名稱,和實際的參數數量向對應,例如上面sort函數中的閉包有兩個參數,系統會自動生成$0和$1這兩個參數名,開發者可以直接使用,因為參數列表都會省略了,那么也不再需要閉包關鍵字in來分隔參數列表與函數體,這時,閉包的寫法實際上變成了如下的模樣:

array = array.sort({$0<$1})

你沒有看錯,加上左右的大括號,一共7個字符,完成了一個排序算法。除了Swift,我不知道是否還有第二種語言可以做到。拋開閉包不說,Swift中還有一種語法,其可以定義類型的運算符方法,例如String類型可以通過=,<,>來進行比較,實際上是String類中實現了這些運算符方法,在某種意義上說,一個運算符即類似與一個函數,那么好了,sort函數中需要傳入的方法對于某些類型來說實際上只是需要一個運算符,示例如下:

array = array.sort(>)

這次你可以真的震驚了,完成排序新算法只需要一個字符,不折不扣的一個字符。

五、Swift中閉包的更多特點

Swift中的閉包還有一個有趣的特點,首先閉包是作為參數傳入另一個函數中的,因此常規的寫法是將閉包的大括號寫在函數的參數列表小括號中,如果閉包中的代碼很多,這時在代碼結構上來看會變得并不太清晰,為了解決這個問題,Swift中這樣規定:如果這個閉包參數是函數的最后一個參數,開發者可以將其拉出小括號,在函數尾部實現閉包代碼,示例如下:

//閉包結尾func func2(param1:Int,param2:()->Void)->Void{  param2()  print("調用了func2函數")}func2(0){    print("閉包中的內容")}

如果一個函數中只有一個參數,且這個參數是一個閉包,那么開發者使用閉包結尾這種寫法,完全可以將函數的參數列表小括號也省略掉,示例如下:

func func3(param:()->Void)->Void{  param()  print("調用了func3函數")}func3{  print("閉包中的內容")}

Swift中還有一個閉包逃逸的概念,這個很好理解,當閉包作為參數傳遞進函數時,如果這個閉包只在函數中被使用,則開發者可以將這個閉包聲明成非逃逸的,即告訴系統當此函數結束后,這個閉包的聲明周期也將結束,這樣做的好處是可以提高代碼性能,將閉包聲明稱非逃逸的類型使用@noescape關鍵字,示例如下:

func func3(@noescape param:()->Void)->Void{  param()  print("調用了func3函數")}func3{  print("閉包中的內容")}

逃逸的閉包常用于異步的操作,例如這個閉包是異步處理一個網絡請求,只有當請求結束后,閉包的聲明周期才結束。非逃逸的閉包還有一個有趣的特點,在其內部如果需要使用self這個關鍵字,self可以被省略。

閉包也可以被自動的生成,這種閉包被稱為自動閉包,自動閉包可以自動將表達式封裝成閉包,開發者不需要再寫閉包的大括號格式,自動閉包不接收參數,返回值為其中表達式的值。示例如下:

//自動閉包演示var list = [1,2,3,4,5,6]//創建一個顯式閉包let closures = {  list.removeFirst()  list.append(7)}//將打印[1,2,3,4,5,6]print(list)//執行閉包closures()//將打印[2,3,4,5,6,7]print(list)func func4(closure:()->Void) -> Void {  //執行顯式的閉包  closures()}func func5(@autoclosure auto:()->Void) -> Void {  //執行自動閉包  auto()}//顯式閉包 需要大括號func4(closures)//將打印[3,4,5,6,7,7]print(list)//將表達式自動生成閉包func5(list.append(8))//將打印[3,4,5,6,7,7,8]print(list)

自動閉包默認是非逃逸的,如果要使用逃逸的閉包,需要手動聲明,如下:

func func5(@autoclosure(escaping) auto:()->Void) -> Void {  //執行自動閉包  auto()}


注:相關教程知識閱讀請移步到swift教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色婷婷av一区二区三区在线观看| 欧美性受xxxx白人性爽| 九九九热精品免费视频观看网站| 668精品在线视频| 美女性感视频久久久| 国产视频亚洲视频| 欧美激情乱人伦一区| 日韩免费观看视频| 综合激情国产一区| 亚洲美女激情视频| 日韩在线欧美在线| 国产精品久久久91| 亚洲国产欧美一区| 中文字幕在线精品| 国产精品99久久久久久www| 日韩在线免费av| 久久精品国产电影| 国产免费成人av| 亚洲天堂av电影| 在线观看国产精品淫| 狠狠做深爱婷婷久久综合一区| 秋霞成人午夜鲁丝一区二区三区| 91色在线观看| 国产精品亚洲片夜色在线| 国产亚洲一级高清| 久久激情五月丁香伊人| 一区二区三区回区在观看免费视频| 97香蕉超级碰碰久久免费的优势| 久久婷婷国产麻豆91天堂| 国产一区二区丝袜高跟鞋图片| 欧美老女人www| 91黄色8090| 久久精品视频99| 国产视频久久网| 亚洲激情电影中文字幕| 91色p视频在线| 欧美在线视频免费| 国产va免费精品高清在线观看| 亚洲影院色在线观看免费| 亚洲男人av电影| 亚洲成色777777在线观看影院| 欧美电影在线观看| 国产福利精品av综合导导航| 亚洲天堂男人天堂女人天堂| 亚洲精品中文字幕av| 亚洲永久免费观看| 欧美精品一二区| 欧美日韩国产色视频| 26uuu另类亚洲欧美日本老年| 91精品国产精品| 国产精品激情av电影在线观看| 国产精品免费视频xxxx| 久久av在线播放| 亚洲欧美制服另类日韩| 欧美精品免费播放| 国产精品美女免费看| 搡老女人一区二区三区视频tv| 国产亚洲欧美aaaa| 亚洲精品国偷自产在线99热| 国产不卡视频在线| 亚洲精品一区久久久久久| 国产精品久久久久久久久久久久| 91精品国产91久久久久久久久| 清纯唯美亚洲综合| 久久的精品视频| 国产一区二区三区在线观看视频| 日韩精品视频观看| 成人在线播放av| 亚洲精品国精品久久99热| 欧美日韩成人在线播放| 欧美日韩亚洲高清| 国产女精品视频网站免费| 久久人人爽人人爽爽久久| 欧美午夜丰满在线18影院| 久久精品视频免费播放| 亚洲福利视频久久| 亚洲国产精彩中文乱码av| 国产精品日韩在线观看| 精品亚洲国产成av人片传媒| 亚洲国内精品视频| 日韩欧美亚洲成人| 成人免费在线视频网站| 2019精品视频| 色小说视频一区| 亚洲人精品午夜在线观看| 清纯唯美日韩制服另类| 日韩免费高清在线观看| 国产91精品久久久久| 日韩中文视频免费在线观看| 亚洲电影av在线| 亚洲精品99久久久久中文字幕| 亚洲最大在线视频| 97视频在线免费观看| 日韩欧美亚洲国产一区| 伊人亚洲福利一区二区三区| 亚洲欧美日韩精品久久奇米色影视| 亚洲成色999久久网站| 欧美一区二区三区免费观看| 久久在精品线影院精品国产| 日韩电视剧在线观看免费网站| 亚洲最大激情中文字幕| 亚洲激情在线观看视频免费| 欧美性jizz18性欧美| 亚洲一区国产精品| 日韩精品极品在线观看播放免费视频| 精品毛片网大全| 久久精品亚洲国产| 欧美影院久久久| 日韩在线视频观看| 欧美日韩人人澡狠狠躁视频| 懂色av一区二区三区| 亚洲欧美中文另类| 欧美成人精品在线观看| 亚洲最新视频在线| 亚洲国产高清高潮精品美女| 久久久久久12| 久久人91精品久久久久久不卡| 国产精品爽黄69天堂a| 亚洲欧美中文字幕| 中文字幕亚洲综合| 亚洲精品国产欧美| 亚洲深夜福利视频| 日av在线播放中文不卡| 欧美午夜激情小视频| 欧美成人午夜视频| 亚洲va久久久噜噜噜| 亚洲人成电影网站色…| 欧美亚洲一级片| 国产精品稀缺呦系列在线| 色777狠狠综合秋免鲁丝| 欧美日韩国产综合新一区| 久热国产精品视频| 久久中文字幕在线| 国产欧美精品在线| 92国产精品视频| 成人av电影天堂| 日韩av最新在线| 久久九九免费视频| 亚洲第一精品自拍| 亚洲aⅴ男人的天堂在线观看| 国产免费亚洲高清| 亚洲精品网址在线观看| 亚洲女人天堂网| 欧美日韩在线免费观看| 欧美激情aaaa| 性色av一区二区三区| 亚洲国产成人在线播放| 成人性生交xxxxx网站| 国产伊人精品在线| 亚洲欧美国内爽妇网| 国产精品日韩在线| 国产在线久久久| 亚洲精品视频免费| 91色视频在线导航| 欧美国产日韩视频| 国产精品成人播放| 国产精品视频公开费视频| 在线观看精品国产视频| 久久精品国产96久久久香蕉| 亚洲欧美中文日韩在线v日本| 日韩天堂在线视频| 亚洲一区亚洲二区| 国产精品v日韩精品| 992tv在线成人免费观看|