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

2022-09-20 22:03:13 字數 4646 閱讀 3655

一、引言

函式是有特定功能的**段,函式會有乙個特定的名稱呼叫時來使用。swift提供了十分靈活的方式來建立與呼叫函式。事實上在swift,每個函式都是一種型別,這種型別由引數和返回值來決定。swift和objective-c的一大區別就在於swift中的函式可以進行巢狀。

而swift中的閉包是有一定功能的**塊,這十分類似於objective-c中的block語法。swift中的閉包語法風格十分簡潔,其作用和函式的作用相似。

二、函式的建立與呼叫

函式通過函式名,引數和返回值來定義,引數和返回值決定乙個函式的型別,在呼叫函式時,使用函式名來進行呼叫,示例如下:

//傳入乙個名字 列印並將其返回

func printname(name:string) -> string

//進行函式的呼叫

printname("hs")

也可以建立沒有引數的函式:

func onepusetwo()->int

onepusetwo()

同樣也可以建立沒有返回值的函式:

func sayhello()

sayhello()

上面介紹的函式型別都比較常見,對於多返回值的函式,在objective-c中十分難處理,開發者通常會採用字典、陣列等集合方式或者乾脆使用block**,在swift中,可以使用元組作為函式的返回值,示例如下:

func tuples()->(int,string)

tuples()

也可以是函式返回乙個optional型別的值,支援返回nil,示例如下:

func func1(param:int)->int?

return param

}func1(0)

func1(1)

在函式的引數名前,開發者還可以再為其新增乙個引數名稱作為外部引數名,示例如下:

func func1(count param:int ,count2 param2:int)->int?

return param

}//外部呼叫使用count

func1(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)

func4(3,param3:3)

還有一種情形在objective-c中也很處理,對於引數數量不定的函式,在前面章節介紹過,objective-c一般會使用list指標來完成,在swift中編寫這樣的函式十分簡單,示例如下:

func func5(param:int...)

}func5(1,2,3,4)

swift中引數預設是常量,在函式中是不能修改外部傳入引數的值得,如果有需求,需要將引數宣告成inout型別,示例如下:

func func6(inout param:int)

var count = 1

//實際上傳入的是引數位址

func6(&count)

print(count)

三、函式型別

函式是一種特殊的資料型別,每乙個函式屬於一種資料型別,示例如下:

func func7(a:int,_ b:int)->int

var addfunc:(int,int)->int = func7

addfunc(1,2)

函式也可以作為引數傳入另乙個函式,這十分類似於objective-c中的block語法,示例如下:

func func7(a:int,_ b:int)->int

var addfunc:(int,int)->int = func7

addfunc(1,2)

func func8(param:int,param2:int,param3:(int,int)->int) -> int

//傳入函式

func8(1, param2: 2, param3: addfunc)

//閉包的方式

func8(2, param2: 2, param3:)

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

func func9()->(int)->int

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

//通過傳入函式的方式

//array = [64,21,5,3,2]

array = array.sort(func1)

//通過閉包的方式

//array = [2,3,5,21,64]

array = array.sort()

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

array = array.sort()

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

array = array.sort(

func2(0)

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

func func3(param:()->void)->void

func3

swift中還有乙個閉包逃逸的概念,這個很好理解,當閉包作為引數傳遞進函式時,如果這個閉包只在函式中被使用,則開發者可以將這個閉包宣告成非逃逸的,即告訴系統當此函式結束後,這個閉包的宣告週期也將結束,這樣做的好處是可以提高**效能,將閉包宣告稱非逃逸的型別使用@noescape關鍵字,示例如下:

func func3(@noescape param:()->void)->void

func3

逃逸的閉包常用於非同步的操作,例如這個閉包是非同步處理乙個網路請求,只有當請求結束後,閉包的宣告週期才結束。非逃逸的閉包還有乙個有趣的特點,在其內部如果需要使用self這個關鍵字,self可以被省略。

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

//自動閉包演示

var list = [1,2,3,4,5,6]

//建立乙個顯式閉包

let closures =

//將列印[1,2,3,4,5,6]

print(list)

//執行閉包

closures()

//將列印[2,3,4,5,6,7]

print(list)

func func4(closure:()->void) -> void

func funwww.cppcns.comc5(@autoclosure auto:()->void) -> void

//顯式閉包 需要大括號

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:()->vwww.cppcns.comoid) -> void

本文標題: 詳解swift中的函式及函式閉包使用

本文位址:

Swift 中的Closures 閉包 詳解

在swift沒有發布之前,所有人使用oc語言編寫cocoa上的程式,而其中經常被人們討論的其中之一 block 一直備受大家的喜愛。在swift中,同樣有這樣的乙個角色,用於當開發者需要非同步執行的之後使用的一種語法 closure。中文翻譯為閉包。本文介紹幾種閉包的形式,以及一些閉包的特性。這是乙...

Swift語法基礎 3 Swift的函式和閉包

在swift中,一樣是存在函式和閉包的,現在讓我們來看看swift的函式和閉包 func person name string,age string string println person xiaoming 20 列印出來的結果 the name is xiaoming,age is 20fun...

Swift基礎(八)函式和閉包

override func viewdidload print arr 執行結果 3,4 3 種閉包簡寫方法 1.省略 引數型別和括號 var arr getlist 1,2,3,4 pre 2.省略 引數型別和括號,return關鍵字 arr getlist 1,2,3,4 pre s in s ...