級(jí)別: ★☆☆☆☆
標(biāo)簽:「iOS」「Swift 5.1」「函數(shù)」「變量參數(shù)」「函數(shù)類(lèi)型」「嵌套函數(shù)」
作者: 沐靈洛
審校: QiShare團(tuán)隊(duì)
Functions:函數(shù)
函數(shù)是執(zhí)行特定任務(wù)的獨(dú)立代碼塊。為函數(shù)指定了一個(gè)標(biāo)識(shí)其功能的名稱秕豫,此名稱可用于“調(diào)用”函數(shù)以在需要時(shí)執(zhí)行其任務(wù)砸喻。Swift中的每個(gè)函數(shù)都有一個(gè)類(lèi)型藕施,由函數(shù)的參數(shù)類(lèi)型和返回類(lèi)型組成镀首。可以像Swift中的任何其他類(lèi)型一樣使用此類(lèi)型本姥,這使得將函數(shù)作為參數(shù)傳遞給其他函數(shù)以及從函數(shù)返回函數(shù)變得很容易妻枕。函數(shù)也可以在其他函數(shù)中嵌套使用。
定義和調(diào)用函數(shù)
- 定義函數(shù):定義函數(shù)的名稱+定義函數(shù)的參數(shù)+定義函數(shù)的返回值葛账。
- 調(diào)用函數(shù):使用其名稱調(diào)用該函數(shù)柠衅,傳遞與函數(shù)參數(shù)類(lèi)型匹配的值。
func greet(person: String) -> String {
let greeting = "Hello, " + person + "!"
return greeting
}
//上述方法也可以寫(xiě)為
func greetAgain(person: String) -> String {
return "Hello again, " + person + "!"
}
print(greetAgain(person: "Anna")) //<! "Hello again, Anna!"
函數(shù)參數(shù)和返回值
無(wú)參函數(shù)
函數(shù)不要求必須定義輸入?yún)?shù)籍琳。即使函數(shù)無(wú)參菲宴,在函數(shù)名稱后仍需要括號(hào)。調(diào)用函數(shù)時(shí)趋急,函數(shù)名后面還會(huì)有一對(duì)空括號(hào)喝峦。
func sayHelloWorld() -> String {
return "hello, world"
}
print(sayHelloWorld())//<! "hello, world"
有多個(gè)參數(shù)的函數(shù)
func greet(person: String, alreadyGreeted: Bool) -> String {
if alreadyGreeted {
return greetAgain(person: person)
} else {
return greet(person: person)
}
}
print(greet(person: "Tim", alreadyGreeted: true))//<! "Hello again, Tim!"
沒(méi)有返回值的函數(shù)
函數(shù)不要求必須定義返回值類(lèi)型。
func greet(person: String) {
print("Hello, \(person)!")
}
greet(person: "Dave") //<! "Hello, Dave!"
沒(méi)有定義返回類(lèi)型的函數(shù)返回Void
類(lèi)型的特殊值宣谈。是一個(gè)空元組()
愈犹。
有多個(gè)返回值的函數(shù)
使用元組類(lèi)型作為函數(shù)的返回值類(lèi)型,同時(shí)返回多個(gè)函數(shù)值闻丑。
//定義
func minMax(array: [Int]) -> (min: Int, max: Int) {
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
//調(diào)用
let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("min is \(bounds.min) and max is \(bounds.max)")//<! min is -6 and max is 109
返回值為可選的元組類(lèi)型
若函數(shù)返回的元組類(lèi)型可能為空值時(shí)漩怎,則可以使用可選的元組返回類(lèi)型。通過(guò)在元組類(lèi)型的右括號(hào)后面放置一個(gè)?
來(lái)編寫(xiě)一個(gè)可選的元組返回類(lèi)型嗦嗡,例如(Int勋锤,Int)?
或(String侥祭,Int叁执,Bool)茄厘?
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
使用可選綁定來(lái)檢查minMax(array :)
函數(shù)是否返回nil
if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
print("min is \(bounds.min) and max is \(bounds.max)")
}
函數(shù)的參數(shù)標(biāo)簽和參數(shù)名稱
每個(gè)函數(shù)的參數(shù)都有參數(shù)標(biāo)簽和參數(shù)名稱。調(diào)用函數(shù)時(shí)使用參數(shù)標(biāo)簽谈宛。參數(shù)名稱用于函數(shù)的實(shí)現(xiàn)次哈。默認(rèn)情況下,函數(shù)的參數(shù)名稱
便是其參數(shù)標(biāo)簽
指定參數(shù)標(biāo)簽
在參數(shù)名稱前面編寫(xiě)參數(shù)標(biāo)簽吆录,用空格分隔:
func someFunction(argumentLabel parameterName: Int) {
}
//調(diào)用
someFunction(argumentLabel: 6) // 參數(shù)名稱 parameterName : 6
//方式二窑滞,默認(rèn)情況
func someFunction(parameterName: Int) {
}
someFunction(parameterName: 6)// 參數(shù)名稱 parameterName : 6
省略參數(shù)標(biāo)簽
如果不想要參數(shù)的參數(shù)標(biāo)簽,請(qǐng)用下劃線_
替換明確的參數(shù)標(biāo)簽恢筝。
func someFunction(_ parameterName: Int) {
}
//調(diào)用
someFunction(7)//參數(shù)忽略哀卫,parameterName:7
默認(rèn)參數(shù)值
通過(guò)在該參數(shù)的類(lèi)型之后為參數(shù)賦值來(lái)為函數(shù)中的任何參數(shù)定義默認(rèn)值。如果定義了默認(rèn)值撬槽,則可以在調(diào)用函數(shù)時(shí)省略該參數(shù)此改。
func parameterContainDefaultValue(defaulValue1:Int,defaultValue2:Int=12) {
}
//調(diào)用,兩者皆可以侄柔,
parameterContainDefaultValue(defaulValue1: 12, defaultValue2: 23)
//因?yàn)槟硞€(gè)參數(shù)值定義了默認(rèn)值共啃,因而多出下面的方法。
parameterContainDefaultValue(defaulValue1: 12)
變量參數(shù)
函數(shù)中使用可變參數(shù)勋拟,表示在函數(shù)調(diào)用時(shí)可以向該參數(shù)傳遞特定類(lèi)型的不同數(shù)量的參數(shù)值勋磕。可變參數(shù)接受零或多個(gè)指定類(lèi)型的值敢靡。
可變參數(shù)的表示:通過(guò)在參數(shù)的類(lèi)型名稱后插入...
來(lái)表示可變參數(shù)挂滓。
傳遞給可變參數(shù)的值在函數(shù)體內(nèi)可用作適當(dāng)類(lèi)型的數(shù)組。例如啸胧,一個(gè)Double ...
類(lèi)型的可變參數(shù)在函數(shù)體內(nèi)可用作[Double]
的常量數(shù)組赶站。一個(gè)函數(shù)可能會(huì)有多個(gè)可變參數(shù)。
func arithmeticMean(_ numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {//!< numbers 作為[Double]類(lèi)型的數(shù)組存在
total += number
}
return total / Double(numbers.count)
}
//調(diào)用
let average = arithmeticMean(1,2,3,4)
print("平均數(shù)\(average)")//!< 平均數(shù)2.5
輸入輸出參數(shù)inout
默認(rèn)情況下纺念,函數(shù)參數(shù)是常量贝椿。如果嘗試從該函數(shù)體內(nèi)修改函數(shù)參數(shù)的值會(huì)導(dǎo)致編譯時(shí)錯(cuò)誤。
如果我們需要在函數(shù)體內(nèi)修改參數(shù)的值陷谱,并且在函數(shù)調(diào)用結(jié)束后需要使用被修改過(guò)的參數(shù)的值烙博。那么我們就需要定義該參數(shù)為輸入輸出參數(shù)。類(lèi)似C與Object-C中的指針參數(shù)烟逊。
輸入輸出參數(shù)表示:通過(guò)將inout
關(guān)鍵字放在參數(shù)類(lèi)型之前來(lái)表示輸入輸出參數(shù)渣窜。
注意:只能將變量作為輸入輸出參數(shù)的參數(shù)值進(jìn)行傳遞,不能傳遞常量或文字值作為參數(shù)宪躯,因?yàn)椴荒苄薷某A亢臀淖?/code>乔宿。當(dāng)我們將變量名稱作為參數(shù)傳遞給輸入輸出參數(shù)時(shí),可以在變量名稱前面直接放置
&
符號(hào)访雪,以表示它可以由函數(shù)修改详瑞。
//根據(jù)內(nèi)存地址交換兩個(gè)整型數(shù)值
func changeTwoIntNumbers(_ a:inout Int,_ b:inout Int) {
let temp = a
a = b
b = temp
}
//使用時(shí)需注意不能將類(lèi)型為'Int'的不可變值作為inout參數(shù)傳遞掂林,否則會(huì)報(bào)錯(cuò)
var a = 6
var b = 7
changeTwoIntNumbers(&a, &b)
print("b:\(b),a:\(a)")//!< b:6,a:7
函數(shù)類(lèi)型
每個(gè)函數(shù)都有一個(gè)特定的函數(shù)類(lèi)型,由函數(shù)的參數(shù)類(lèi)型和返回類(lèi)型組成坝橡。函數(shù)類(lèi)型不能帶有參數(shù)標(biāo)簽泻帮。
func addTwoInts(_ a: Int, _ b: Int) -> Int {
return a + b
}
func printHelloWorld() {
print("hello, world")
}
上述示例中的函數(shù)類(lèi)型分別為:(Int, Int) -> Int
和() -> Void
。
使用函數(shù)類(lèi)型
我們可以像使用Swift中的任何其他類(lèi)型一樣使用函數(shù)類(lèi)型驳庭⌒趟常可以將常量或變量定義為函數(shù)類(lèi)型,并為該變量分配適當(dāng)?shù)暮瘮?shù)饲常。
var mathFunction:(Int,Int)->Int = addTwoInts
let addValue = mathFunction(a,b)
mathFunction = subTwoInts(_:_:)
let subValue = mathFunction(a,b)
print(subValue)//!< 1
print(addValue)//!< 13
//定義的函數(shù)
func addTwoInts(_ a: Int, _ b: Int) -> Int {
return a + b
}
func subTwoInts(_ a:Int,_ b:Int)-> Int {
return a - b
}
函數(shù)類(lèi)型作為參數(shù)類(lèi)型
使用函數(shù)類(lèi)型如(Int,Int)- > Int
作為另一個(gè)函數(shù)的參數(shù)類(lèi)型狼讨。
//定義
func mathResultFunction(_ mathCalculate:(Int,Int)->Int,_ a:Int, _ b:Int){
print("函數(shù)計(jì)算的結(jié)果為:\(mathCalculate(a,b))")
}
//調(diào)用
var mathFunction:(Int,Int)->Int = addTwoInts
let addValue = mathFunction(a,b)
mathFunction = subTwoInts(_:_:)
let subValue = mathFunction(a,b)
mathResultFunction(mathFunction, a, b)//!< 函數(shù)計(jì)算的結(jié)果為:1
mathResultFunction(addTwoInts(a:_:), a, b)//!< 函數(shù)計(jì)算的結(jié)果為:13
函數(shù)類(lèi)型作為返回類(lèi)型
使用函數(shù)類(lèi)型作為另一個(gè)函數(shù)的返回類(lèi)型贝淤。
//以下兩個(gè)函數(shù)盡管具有不同的功能,但是都具有相同的函數(shù)類(lèi)型政供,
func stepForward(_ input: Int) -> Int {
return input + 1
}
func stepBackward(_ input: Int) -> Int {
return input - 1
}
//定義返回值類(lèi)型為函數(shù)類(lèi)型的函數(shù)
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
return backward ? stepBackward : stepForward
}
//簡(jiǎn)單使用一下
var currentValue = 3
//! tempChooseStepFunction:stepBackward
let tempChooseStepFunction = chooseStepFunction(backward: currentValue > 0)
while currentValue > 0 {
currentValue = tempChooseStepFunction(currentValue)
print(currentValue)
}//!< 2 1 0
嵌套函數(shù)
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
func stepBackward(_ input: Int) -> Int {
return input - 1
}
func stepForward(input: Int) -> Int {
return input + 1
}
return backward ? stepBackward : stepForward
}
參考資料:
swift 5.1官方編程指南
推薦文章:
Swift 5.1 (5) - 控制流
Xcode11 新建工程中的SceneDelegate
iOS App啟動(dòng)優(yōu)化(二)—— 使用“Time Profiler”工具監(jiān)控App的啟動(dòng)耗時(shí)
iOS App啟動(dòng)優(yōu)化(一)—— 了解App的啟動(dòng)流程
iOS WKWebView的基本使用
Swift 5.1 (4) - 集合類(lèi)型