Swift-函數(shù)

定義和調(diào)用函數(shù)

在下面的例子中的函數(shù)叫做greet(person :)耙旦,因為這是它的作用 - 它需要一個人的名字作為輸入碎罚,并返回一個問候語的人悬荣。 為了實現(xiàn)這一點骑冗,你定義一個輸入?yún)?shù) - 一個String值入撒,稱為person - 和一個String的返回類型隆豹,它將包含該人的問候語:

func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
}

所有這些信息都匯總到函數(shù)的定義中,前綴是func關(guān)鍵字茅逮。 通過返回箭頭 - >(一個連字符后跟一個直角括號)來指示函數(shù)的返回類型璃赡,后面跟著要返回的類型的名稱。

該定義描述了函數(shù)的作用献雅,它期望接收的內(nèi)容碉考,以及它完成后返回的內(nèi)容。 該定義使得函數(shù)可以從代碼中的其他位置輕松調(diào)用:

print(greet(person: "Anna"))
// Prints "Hello, Anna!"
print(greet(person: "Brian"))
// Prints "Hello, Brian!"

要使此函數(shù)的主體更短挺身,可以將消息創(chuàng)建和return語句合并為一行:

func greetAgain(person: String) -> String {
    return "Hello again, " + person + "!"
}
print(greetAgain(person: "Anna"))
// Prints "Hello again, Anna!"

函數(shù)參數(shù)和返回值

無參數(shù)的函數(shù)

func sayHelloWorld() -> String {
    return "hello, world"
}
print(sayHelloWorld())
// Prints "hello, world"

多個參數(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))
// Prints "Hello again, Tim!"

無返回值的函數(shù)

func greet(person: String) {
    print("Hello, \(person)!")
}
greet(person: "Dave")
// Prints "Hello, Dave!"

因為它不需要返回值侯谁,所以函數(shù)的定義不包括返回箭頭( - >)或返回類型。

注意:
嚴格地說章钾,這個版本的greet(person :)函數(shù)仍然返回一個值墙贱,即使沒有定義返回值。 沒有定義的返回類型的函數(shù)返回類型為Void的特殊值贱傀。 這只是一個空的元組惨撇,它寫成()。

調(diào)用函數(shù)時窍箍,可以忽略函數(shù)的返回值:

func printAndCount(string: String) -> Int {
    print(string)
    return string.characters.count
}
func printWithoutCounting(string: String) {
    let _ = printAndCount(string: string)
}
printAndCount(string: "hello, world")
// prints "hello, world" and returns a value of 12
printWithoutCounting(string: "hello, world")
// prints "hello, world" but does not return a value

第一個函數(shù)printAndCount(string :)打印一個字符串串纺,然后將其字符計數(shù)作為Int返回丽旅。 第二個函數(shù)printWithoutCounting(string :)調(diào)用第一個函數(shù),但忽略它的返回值纺棺。 當(dāng)調(diào)用第二個函數(shù)時榄笙,消息仍由第一個函數(shù)打印,但不使用返回的值祷蝌。

具有多個返回值的函數(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)
}

因為元組的成員值被命名為函數(shù)的返回類型的一部分茅撞,所以可以使用點語法訪問它們以檢索最小和最大找到的值:

let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("min is \(bounds.min) and max is \(bounds.max)")
// Prints "min is -6 and max is 109"

注意
元組的成員不需要在從函數(shù)返回元組的點處命名,因為它們的名稱已經(jīng)被指定為函數(shù)的返回類型的一部分巨朦。

可選元組返回類型

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)
}

您可以使用可選綁定來檢查此版本的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)")
}
// Prints "min is -6 and max is 109"

函數(shù)參數(shù)標簽和參數(shù)名稱

每個函數(shù)參數(shù)都具有參數(shù)標簽和參數(shù)名稱米丘。 參數(shù)標簽在調(diào)用函數(shù)時使用; 每個參數(shù)寫在函數(shù)調(diào)用中,其參數(shù)標簽在它之前糊啡。 參數(shù)名稱用于函數(shù)的實現(xiàn)拄查。 默認情況下,參數(shù)使用其參數(shù)名稱作為其參數(shù)標簽棚蓄。

func someFunction(firstParameterName: Int, secondParameterName: Int) {
    // In the function body, firstParameterName and secondParameterName
    // refer to the argument values for the first and second parameters.
}
someFunction(firstParameterName: 1, secondParameterName: 2)

所有參數(shù)必須具有唯一的名稱堕扶。 盡管多個參數(shù)可能具有相同的參數(shù)標簽,但唯一的參數(shù)標簽有助于使代碼更具可讀性梭依。

指定參數(shù)標簽

您在參數(shù)名稱之前寫入?yún)?shù)標簽稍算,用空格分隔:

func someFunction(argumentLabel parameterName: Int) {
    // In the function body, parameterName refers to the argument value
    // for that parameter.
}

這里有一個greet(person :)函數(shù)的變體,它使用一個人的姓名和家鄉(xiāng)并返回問候語:

func greet(person: String, from hometown: String) -> String {
    return "Hello \(person)!  Glad you could visit from \(hometown)."
}
print(greet(person: "Bill", from: "Cupertino"))
// Prints "Hello Bill!  Glad you could visit from Cupertino."

省略參數(shù)標簽

如果不想要參數(shù)的參數(shù)標簽役拴,請為該參數(shù)編寫下劃線(_)糊探,而不是顯式參數(shù)標簽。

func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
    // In the function body, firstParameterName and secondParameterName
    // refer to the argument values for the first and second parameters.
}
someFunction(1, secondParameterName: 2)

注意:
如果參數(shù)具有參數(shù)標簽河闰,則在調(diào)用函數(shù)時必須標記參數(shù)科平。

默認參數(shù)值

您可以通過為該參數(shù)的類型之后的參數(shù)分配值來為該函數(shù)中的任何參數(shù)定義默認值。 如果定義了默認值淤击,則可以在調(diào)用該函數(shù)時忽略該參數(shù)匠抗。

func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
    // If you omit the second argument when calling this function, then
    // the value of parameterWithDefault is 12 inside the function body.
}
someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6) // parameterWithDefault is 6
someFunction(parameterWithoutDefault: 4) // parameterWithDefault is 12

將沒有默認值的參數(shù)放在函數(shù)的參數(shù)列表的開頭故源,在具有默認值的參數(shù)之前污抬。 沒有默認值的參數(shù)通常對函數(shù)的意義更重要。

變量參數(shù)

傳遞給可變參數(shù)的值在函數(shù)體內(nèi)作為適當(dāng)類型的數(shù)組使用绳军。 例如印机,具有數(shù)字名稱和Double ...類型的可變參數(shù)在函數(shù)體內(nèi)作為稱為[Double]類型的常數(shù)數(shù)組。下面的示例計算任何長度的數(shù)字列表的算術(shù)平均值(也稱為平均值):

func arithmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers

輸入 - 輸出參數(shù)

  • 默認情況下门驾,函數(shù)參數(shù)是常量射赛。試圖從函數(shù)體內(nèi)更改函數(shù)參數(shù)的值會導(dǎo)致編譯時錯誤。這意味著您不能錯誤地更改參數(shù)的值奶是。如果希望函數(shù)修改參數(shù)的值楣责,并且希望這些更改在函數(shù)調(diào)用結(jié)束后保留??竣灌,請將該參數(shù)定義為in-out參數(shù)。

  • 您通過將inout參數(shù)放在參數(shù)類型之前來編寫in-out參數(shù)秆麸。輸入 - 輸出參數(shù)具有傳遞到函數(shù)的值初嘹,由函數(shù)修改,并被傳回函數(shù)以替換原始值沮趣。有關(guān)輸入?yún)?shù)和關(guān)聯(lián)編譯器優(yōu)化行為的詳細討論屯烦,請參閱輸入?yún)?shù)。

  • 您只能將一個變量作為in-out參數(shù)的參數(shù)傳遞房铭。您不能將常量或字面值作為參數(shù)傳遞驻龟,因為常量和字面值不能修改。在將變量的名稱作為參數(shù)傳遞給in-out參數(shù)時缸匪,在變量名稱前放置一個&符號(&)翁狐,以指示它可以由函數(shù)修改。

注意:
輸入 - 輸出參數(shù)不能具有默認值凌蔬,并且可變參數(shù)不能標記為輸入谴蔑。

下面是一個名為swapTwoInts( :)的函數(shù)的示例,它有兩個in-out整數(shù)參數(shù)a和b:

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

swapTwoInts( :)函數(shù)只是將b的值轉(zhuǎn)換為a龟梦,將a的值轉(zhuǎn)換為b隐锭。 該函數(shù)通過將a的值存儲在名為temporaryA的臨時常量中,將b的值分配給a计贰,然后將temporaryA分配給b來執(zhí)行此交換钦睡。

您可以調(diào)用具有兩個Int類型變量的swapTwoInts( :)函數(shù)來交換它們的值。 請注意躁倒,someInt和anotherInt的名稱在傳遞給swapTwoInts( :)函數(shù)時荞怒,以&符號作為前綴:

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"

上面的示例顯示,someInt和anotherInt的原始值由swapTwoInts( :)函數(shù)修改秧秉,即使它們最初在函數(shù)之外定義褐桌。

輸入 - 輸出參數(shù)與函數(shù)返回值不同。 上面的swapTwoInts示例沒有定義返回類型或返回值象迎,但它仍然修改someInt和anotherInt的值荧嵌。 輸入 - 輸出參數(shù)是函數(shù)具有超出函數(shù)體范圍的效果的替代方法。

函數(shù)類型

每個函數(shù)都有一個特定的函數(shù)類型砾淌,由參數(shù)類型和函數(shù)的返回類型組成啦撮。

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}
func multiplyTwoInts(_ a: Int, _ b: Int) -> Int {
    return a * b
}

此示例定義了兩個簡單的數(shù)學(xué)函數(shù),稱為addTwoInts和multiplyTwoInts汪厨。 這些函數(shù)各取兩個Int值赃春,并返回一個Int值。

你在Swift中使用類似任何其他類型的函數(shù)類型劫乱。 例如织中,您可以將常量或變量定義為函數(shù)類型锥涕,并為該變量分配適當(dāng)?shù)暮瘮?shù):

var mathFunction: (Int, Int) -> Int = addTwoInts

這可以看作:

  • “定義一個名為mathFunction的變量,它的類型是一個函數(shù)狭吼,它接受兩個Int值站楚,并返回一個Int值。設(shè)置這個新變量以引用稱為addTwoInts的函數(shù)搏嗡。

  • addTwoInts( :)函數(shù)與mathFunction變量具有相同的類型窿春,因此Swift的類型檢查器允許此賦值。現(xiàn)在可以調(diào)用名為mathFunction的已分配函數(shù):

print("Result: \(mathFunction(2, 3))")
// Prints "Result: 5"

與任何其他類型一樣采盒,當(dāng)您將函數(shù)分配給常量或變量時旧乞,您可以將其留給Swift來推斷函數(shù)類型:

let anotherMathFunction = addTwoInts
// anotherMathFunction is inferred to be of type (Int, Int) -> Int

函數(shù)作為參數(shù)

func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// Prints "Result: 8"

函數(shù)作為返回值

func stepForward(_ input: Int) -> Int {
    return input + 1
}
func stepBackward(_ input: Int) -> Int {
    return input - 1
}

這里有一個名為chooseStepFunction(backward :)的函數(shù),它的返回類型是(Int) - > Int磅氨。 chooseStepFunction(backward :)函數(shù)基于一個名為backward的布爾參數(shù)返回stepForward(_ :)函數(shù)或stepBackward(_ :)函數(shù):

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    return backward ? stepBackward : stepForward
}

你現(xiàn)在可以使用chooseStepFunction(backward :)來獲取一個方向或另一個方向的函數(shù):

var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function
print("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// 3...
// 2...
// 1...
// zero!

嵌套函數(shù)

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backward ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尺栖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子烦租,更是在濱河造成了極大的恐慌延赌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叉橱,死亡現(xiàn)場離奇詭異挫以,居然都是意外死亡,警方通過查閱死者的電腦和手機窃祝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門掐松,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粪小,你說我怎么就攤上這事大磺。” “怎么了探膊?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵杠愧,是天一觀的道長。 經(jīng)常有香客問我逞壁,道長流济,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任猾担,我火速辦了婚禮袭灯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绑嘹。我一直安慰自己,他們只是感情好橘茉,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布工腋。 她就那樣靜靜地躺著姨丈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪擅腰。 梳的紋絲不亂的頭發(fā)上蟋恬,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音趁冈,去河邊找鬼歼争。 笑死,一個胖子當(dāng)著我的面吹牛渗勘,可吹牛的內(nèi)容都是我干的沐绒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼旺坠,長吁一口氣:“原來是場噩夢啊……” “哼乔遮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起取刃,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蹋肮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后璧疗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坯辩,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年崩侠,在試婚紗的時候發(fā)現(xiàn)自己被綠了濒翻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡啦膜,死狀恐怖有送,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情僧家,我是刑警寧澤雀摘,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站八拱,受9級特大地震影響阵赠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肌稻,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一清蚀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爹谭,春花似錦枷邪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽践惑。三九已至,卻和暖如春嘶卧,著一層夾襖步出監(jiān)牢的瞬間尔觉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工芥吟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留侦铜,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓钟鸵,卻偏偏與公主長得像钉稍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子携添,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 函數(shù)是用來完成特定任務(wù)的獨立的代碼塊嫁盲。給一個函數(shù)起一個合適的名字,用來標識函數(shù)做什么烈掠,并且當(dāng)函數(shù)需要執(zhí)行的時候羞秤,這...
    窮人家的孩紙閱讀 811評論 2 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)左敌,斷路器瘾蛋,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 86.復(fù)合 Cases 共享相同代碼塊的多個switch 分支 分支可以合并, 寫在分支后用逗號分開。如果任何模式...
    無灃閱讀 1,366評論 1 5
  • 中國人民大學(xué)是一所以人文社會科學(xué)為主的綜合性研究型全國重點大學(xué)矫限,直屬于教育部哺哼,由教育部與北京市共建,是國家“985...
    道法自然008閱讀 920評論 0 0
  • 段總閱讀 175評論 0 0