在本文中,您將學(xué)習(xí)不同的用戶定義函數(shù),這些函數(shù)將通過示例獲取不同類型的輸入并返回輸出。
在上一篇文章Swift 函數(shù)中,我們了解了函數(shù)?,F(xiàn)在,我們將探討在Swift中創(chuàng)建函數(shù)的不同方式和類型,即在函數(shù)中處理輸入和輸出。
這些類型的函數(shù)不接受任何輸入和返回值。
func funcname() { //語句 } 或者 func funcname() -> () { //語句 } 或者 func funcname() -> Void { //語句 }
以上所有語法對于創(chuàng)建不帶參數(shù)且不返回值的函數(shù)都是有效的。
上面的語法func funcname()->()也等同于func funcname()->void,因為void只是()的一個類型別名。您可以訪問Swift 類型別名來了解更多信息。
func greetUser() { print("Good Morning!") } greetUser()
當(dāng)您運行上述程序時,輸出將是:
Good Morning!
這些類型的函數(shù)不接受任何輸入?yún)?shù),而是返回一個值。要添加返回類型,您需要添加箭頭(->)和返回類型。
func funcname() -> ReturnType { //語句 return value }
func greetUser() -> String { return "Good Morning!" } let msg = greetUser() print(msg)
當(dāng)您運行上述程序時,輸出將是:
Good Morning!
在上面的程序中,您將返回類型定義為String?,F(xiàn)在,該語句必須從函數(shù)內(nèi)部的語句中返回一個字符串,否則您將拋出錯誤。
return 關(guān)鍵字將程序的控制權(quán)從函數(shù)主體轉(zhuǎn)移到函數(shù)調(diào)用。如果需要從函數(shù)返回值,請在 return 關(guān)鍵字后面添加要返回的值。
return "Good Morning!" 語句從函數(shù)返回String 類型的值。請注意,返回值的類型和值必須匹配。
您還可以將返回值分配給變量或常量。let msg = 將返回值分配給常量 msg。因此該語句 print(msg )輸出“Good Morning!”。
如果您想忽略該值,則只需使用下劃線 _ ,即 let _ =。
參數(shù)用于在函數(shù)中輸入。參數(shù)包含參數(shù)名稱和類型,后跟冒號(:)。這些類型的函數(shù)采用輸入?yún)?shù),但不返回值。
func funcname(parameterName:Type) { //語句 }
func greetUser(msg:String) { print(msg) } greetUser(msg: "Good Morning!")
當(dāng)您運行上述程序時,輸出將是:
Good Morning!
在上述程序中,該函數(shù)接受字符串類型的單個參數(shù)。該參數(shù)只能在函數(shù)內(nèi)部使用。msg是參數(shù)的名稱。
您可以通過向函數(shù)傳遞參數(shù)名稱為 msg 的字符串值來調(diào)用函數(shù) greetUser(msg: "Good Morning!")。該參數(shù)名稱只在 greetUser() 函數(shù)內(nèi)部可見。
因此,print(msg)語句輸出 “Good Morning!”。
這些類型的函數(shù)使用參數(shù)并返回值。
func funcname(parameterName:Type) -> ReturnType { //語句 }
func greetUser(name:String) -> String { return "Good Morning! " + name } let msg = greetUser(name: "Jack") print(msg)
當(dāng)您運行上述程序時,輸出將是:
Good Morning! Jack
在上面的程序中,該函數(shù)接受String類型的單個參數(shù),并且還返回String類型的值“Good Morning! Jack”。
這些類型的函數(shù)采用以逗號分隔的多個參數(shù),并且還返回多個值。您可以使用元組在Swift中返回多個值。
func funcname(parameterName:Type, parameterName2:Type ,...) -> (ReturnType, ReturnType...) { //語句 }
func greetUser(name:String, age:Int) -> (String, Int) { let msg = "Good Morning!" + name var userage = age if age < 0 { userage = 0 } return (msg, userage) } let msg = greetUser(name: "Jack", age: -2) print(msg.0) print("You have \(msg.1) coins left")
當(dāng)您運行上述程序時,輸出將是:
Good Morning!Jack You have 0 coins left
在以上程序中,該函數(shù)greetUser()接受類型為 String和 Int 的多個參數(shù)。該函數(shù)還返回多個值,類型為String 和 Int。
為了訪問每個返回值,我們使用索引位置0,1,…在這里,我們使用 msg.0 訪問 “ Good Morning!Jack ”和 msg.1 訪問“0”。
使用索引位置有時可能是不直觀和不可讀的。我們可以通過為返回值命名來優(yōu)雅地解決這個問題。上面的程序也可以按照下面的方式重寫。
func greetUser(name:String, coins:Int) -> (name:String, coins:Int) { let msg = "Good Morning!" + name var userCoins = coins if coins < 0 { userCoins = 0 } return (msg, userCoins) } let msg = greetUser(name: "Jack",coins: -2) print(msg.name) print("You have \(msg.coins) coins left")
在此程序中,返回類型為元組,其中包含具有該類型的變量名稱。這樣做的主要優(yōu)點是您可以使用變量名 msg.name和 msg.coins 代替 msg.0和 msg.1 來訪問結(jié)果。
定義接受輸入的函數(shù)時,可以在參數(shù)名稱的幫助下定義輸入名稱。但是,還有另一種名稱可以與參數(shù)名稱一起使用,稱為參數(shù)標簽。
自變量標簽的使用允許以表達方式,類似于句子的方式調(diào)用函數(shù),同時仍提供可讀且意圖明確的函數(shù)主體。
每個函數(shù)參數(shù)都具有參數(shù)標簽和參數(shù)名稱。默認情況下,參數(shù)使用其參數(shù)名稱作為其參數(shù)標簽。但是,如果您明確定義了參數(shù)名稱,則在調(diào)用函數(shù)時會使用參數(shù)標簽。
帶參數(shù)標簽的函數(shù)的語法為
func funcname(argumentLabel parameterName:Type)-> Return Type { //語句 }
讓我們在下面的示例中看到這一點。
func sum(a:Int, b:Int) -> Int { return a + b } let result = sum(a: 2, b: 3) print("The sum is \(result)")
當(dāng)您運行上述程序時,輸出將是:
The sum is 5
在上面的示例中,我們沒有指定參數(shù)標簽,因此在調(diào)用函數(shù)時它將使用默認參數(shù)名稱a和b作為參數(shù)標簽。
當(dāng)調(diào)用函數(shù)時,您可能會注意到函數(shù)調(diào)用不是表達性的/句子。 如果您可以將函數(shù)調(diào)用設(shè)置為:
let result = sum(of: 2, and: 3)
現(xiàn)在讓我們將函數(shù)更改為:
func sum(of:Int, and:Int) -> Int { return of + and } let result = sum(of: 2, and: 3) print("The sum is \(result)")
現(xiàn)在,方法調(diào)用是可表達的。但是,現(xiàn)在我們必須使用參數(shù)名稱of& and,return of + and 來查找兩個數(shù)字的和。現(xiàn)在,這使得函數(shù)體可讀性較差。在函數(shù)體內(nèi)使用a和b代替of&and將更有意義。
為此,我們必須將參數(shù)標簽明確定義為:
func sum(of a :Int, and b:Int) -> Int { return a + b } let result = sum(of: 2, and: 3) print("The sum is \(result)")
在上述程序中,該函數(shù)接受Int類型的兩個參數(shù)。函數(shù)調(diào)用使用參數(shù)標簽of&and,這在調(diào)用函數(shù)sum(of: 2, and: 3),而不是 sum(a: 2, b: 3)。
另外,函數(shù)主體使用參數(shù)名稱a和b,而不是of&and,這在應(yīng)用操作時也更有意義。
您還可以通過在參數(shù)名稱前寫一個下劃線 _ 來省略參數(shù)標簽。
func sum(_ a :Int, _ b:Int) -> Int { return a + b } let result = sum(2, 3) print("The sum is \(result)")
您可以為函數(shù)中的任何參數(shù)提供默認值,方法是在該參數(shù)的類型之后為該參數(shù)分配一個值。提供默認參數(shù)可以使您在調(diào)用函數(shù)時忽略該參數(shù)。
如果在調(diào)用函數(shù)時未將值傳遞給參數(shù),則使用其默認值。但是,如果在調(diào)用時將值顯式傳遞給參數(shù),則使用指定的值。
func funcname(parameterName:Type = value) -> Return Type { //語句 }
func sum(of a :Int = 7, and b:Int = 8) -> Int { return a + b } let result1 = sum(of: 2, and: 3) print("The sum is \(result1)") let result2 = sum(of: 2) print("The sum is \(result2)") let result3 = sum(and: 2) print("The sum is \(result3)") let result4 = sum() print("The sum is \(result4)")
當(dāng)您運行上述程序時,輸出將是:
The sum is 5 The sum is 10 The sum is 9 The sum is 15
在上面的程序中,該函數(shù)sum(of a :Int = 7 , and b:Int = 8) -> Int接受兩個Int類型的參數(shù),并且指定了參數(shù)a=7和b=8的默認值。
如果在函數(shù)調(diào)用中將value作為參數(shù)傳遞,sum(of: 2, and: 3) 則使用2和3代替參數(shù)默認值。
但是如果您不將參數(shù)值作為sum()傳遞,那么將使用默認值7和8作為參數(shù)值。
可變參數(shù)可以接受零個或多個特定類型的值。您可以通過在參數(shù)的類型名稱后插入三個句點字符(...)來指定可變參數(shù)。
當(dāng)需要在調(diào)用函數(shù)時將各種數(shù)量的輸入值傳遞給參數(shù)時,通常使用可變參數(shù)。例如,數(shù)字列表,字母列表等。
具有可變參數(shù)的函數(shù)的語法為:
func funcname(parameterName:Type...) -> Return Type { //語句 }
func sum(of numbers:Int...) { var result = 0 for num in numbers { result += num } print("數(shù)的總和是 \(result)") } sum(of: 1, 2, 3, 4, 5, 6, 7, 8)
在上述程序中,該函數(shù)sum(of numbers:Int...)接受Int類型的可變參數(shù)??勺儏?shù)可以接受多個以逗號分隔的值 sum(of: 1, 2, 3, 4, 5, 6, 7, 8)。
作為可變參數(shù)傳遞的值1、2、3、4、5、6、7、8在函數(shù)體內(nèi)可以作為Int類型數(shù)組使用。因此,我們可以將for-in循環(huán)應(yīng)用為for num in numbers。
當(dāng)您運行上述程序時,輸出將是:
數(shù)的總和是 36
注意:Swift內(nèi)置print()函數(shù)還接受任意類型的可變參數(shù)。
Any表示Swift中的任何數(shù)據(jù)類型,例如Int、Float、Double、String等。
定義函數(shù)參數(shù)時,無法在體內(nèi)修改函數(shù)參數(shù)。因此,默認情況下它們是常量。讓我們在示例中看一下:
func process(name:String) { if name == ""{ name = "guest" } }
上面的程序會導(dǎo)致編譯時錯誤,因為您無法更改參數(shù)的值。
如果要讓函數(shù)修改參數(shù)值,則需要將參數(shù)定義為 in-out 參數(shù)。您可以通過將 inout 關(guān)鍵字放在參數(shù)類型的前面來編寫輸入/輸出參數(shù)。
在后臺,一個in-out參數(shù)具有一個值,該值傳遞到函數(shù)中,由函數(shù)修改,然后從函數(shù)中傳遞回以替換原始值。因此,函數(shù)調(diào)用中傳遞的值不能為常量。您必須將其聲明為變量。
具有inout參數(shù)的函數(shù)的語法為:
func funcname(parameterName:inout Type) -> Return Type { //語句 }
func process(name:inout String) { if name == ""{ name = "guest" } } var userName = "" process(name: &userName) print(userName)
當(dāng)您運行上述程序時,輸出將是:
guest
在上面的程序中,我們聲明了一個接受inout參數(shù)的函數(shù),以便可以在函數(shù)體內(nèi)更改/更改參數(shù) name。
在將參數(shù)傳遞給in-out參數(shù)時,必須在變量名前直接使用&號,以便函數(shù)可以修改它。