欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

2.6函數(shù)(Functions)-創(chuàng)新互聯(lián)

本頁包含內(nèi)容:

10年積累的成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)制作后付款的網(wǎng)站建設(shè)流程,更有蒙山免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
  • 函數(shù)定義與調(diào)用(Defining and Calling Functions)

  • 函數(shù)參數(shù)與返回值(Function Parameters and Return Values)

  • 函數(shù)參數(shù)名稱(Function Parameter Names)

  • 函數(shù)類型(Function Types)

  • 函數(shù)嵌套(Nested Functions)

函數(shù)是用來完成特定任務(wù)的獨(dú)立的代碼塊。你給一個(gè)函數(shù)起一個(gè)合適的名字,用來標(biāo)識(shí)函數(shù)做什么,并且當(dāng)函數(shù)需要執(zhí)行的時(shí)候,這個(gè)名字會(huì)被“調(diào)用”。

Swift 統(tǒng)一的函數(shù)語法足夠靈活,可以用來表示任何函數(shù),包括從最簡單的沒有參數(shù)名字的 C 風(fēng)格函數(shù),到復(fù)雜的帶局部和外部參數(shù)名的 Objective-C 風(fēng)格函數(shù)。參數(shù)可以提供默認(rèn)值,以簡化函數(shù)調(diào)用。參數(shù)也可以既當(dāng)做傳入?yún)?shù),也當(dāng)做傳出參數(shù),也就是說,一旦函數(shù)執(zhí)行結(jié)束,傳入的參數(shù)值可以被修改。

在 Swift 中,每個(gè)函數(shù)都有一種類型,包括函數(shù)的參數(shù)值類型和返回值類型。你可以把函數(shù)類型當(dāng)做任何其他普通變量類型一樣處理,這樣就可以更簡單地把函數(shù)當(dāng)做別的函數(shù)的參數(shù),也可以從其他函數(shù)中返回函數(shù)。函數(shù)的定義可以寫在在其他函數(shù)定義中,這樣可以在嵌套函數(shù)范圍內(nèi)實(shí)現(xiàn)功能封裝。

函數(shù)的定義與調(diào)用(Defining and Calling Functions)

當(dāng)你定義一個(gè)函數(shù)時(shí),你可以定義一個(gè)或多個(gè)有名字和類型的值,作為函數(shù)的輸入(稱為參數(shù),parameters),也可以定義某種類型的值作為函數(shù)執(zhí)行結(jié)束的輸出(稱為返回類型)。

每個(gè)函數(shù)有個(gè)函數(shù)名,用來描述函數(shù)執(zhí)行的任務(wù)。要使用一個(gè)函數(shù)時(shí),你用函數(shù)名“調(diào)用”,并傳給它匹配的輸入值(稱作實(shí)參,arguments)。一個(gè)函數(shù)的實(shí)參必須與函數(shù)參數(shù)表里參數(shù)的順序一致。

在下面例子中的函數(shù)叫做"greetingForPerson",之所以叫這個(gè)名字是因?yàn)檫@個(gè)函數(shù)用一個(gè)人的名字當(dāng)做輸入,并返回給這個(gè)人的問候語。為了完成這個(gè)任務(wù),你定義一個(gè)輸入?yún)?shù)-一個(gè)叫做 personName 的String 值,和一個(gè)包含給這個(gè)人問候語的 String 類型的返回值:

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

所有的這些信息匯總起來成為函數(shù)的定義,并以 func 作為前綴。指定函數(shù)返回類型時(shí),用返回箭頭->(一個(gè)連字符后跟一個(gè)右尖括號(hào))后跟返回類型的名稱的方式來表示。

該定義描述了函數(shù)做什么,它期望接收什么和執(zhí)行結(jié)束時(shí)它返回的結(jié)果是什么。這樣的定義使的函數(shù)可以在別的地方以一種清晰的方式被調(diào)用:

println(sayHello("Anna"))
// prints "Hello, Anna!"
println(sayHello("Brian"))
// prints "Hello, Brian!"

調(diào)用 sayHello 函數(shù)時(shí),在圓括號(hào)中傳給它一個(gè) String 類型的實(shí)參。因?yàn)檫@個(gè)函數(shù)返回一個(gè) String 類型的值,sayHello 可以被包含在 println 的調(diào)用中,用來輸出這個(gè)函數(shù)的返回值,正如上面所示。

在 sayHello 的函數(shù)體中,先定義了一個(gè)新的名為 greeting 的 String 常量,同時(shí)賦值了給personName 的一個(gè)簡單問候消息。然后用 return 關(guān)鍵字把這個(gè)問候返回出去。一旦return greeting 被調(diào)用,該函數(shù)結(jié)束它的執(zhí)行并返回 greeting 的當(dāng)前值。

你可以用不同的輸入值多次調(diào)用 sayHello。上面的例子展示的是用"Anna"和"Brian"調(diào)用的結(jié)果,該函數(shù)分別返回了不同的結(jié)果。

為了簡化這個(gè)函數(shù)的定義,可以將問候消息的創(chuàng)建和返回寫成一句:

func sayHelloAgain(personName: String) -> String {
    return "Hello again, " + personName + "!"
}
println(sayHelloAgain("Anna"))
// prints "Hello again, Anna!"

函數(shù)參數(shù)與返回值(Function Parameters and Return Values)

函數(shù)參數(shù)與返回值在Swift中極為靈活。你可以定義任何類型的函數(shù),包括從只帶一個(gè)未名參數(shù)的簡單函數(shù)到復(fù)雜的帶有表達(dá)性參數(shù)名和不同參數(shù)選項(xiàng)的復(fù)雜函數(shù)。

多重輸入?yún)?shù)(Multiple Input Parameters)

函數(shù)可以有多個(gè)輸入?yún)?shù),寫在圓括號(hào)中,用逗號(hào)分隔。

下面這個(gè)函數(shù)用一個(gè)半開區(qū)間的開始點(diǎn)和結(jié)束點(diǎn),計(jì)算出這個(gè)范圍內(nèi)包含多少數(shù)字:

func halfOpenRangeLength(start: Int, end: Int) -> Int {
    return end - start
}
println(halfOpenRangeLength(1, 10))
// prints "9"

無參函數(shù)(Functions Without Parameters)

函數(shù)可以沒有參數(shù)。下面這個(gè)函數(shù)就是一個(gè)無參函數(shù),當(dāng)被調(diào)用時(shí),它返回固定的 String 消息:

func sayHelloWorld() -> String {
    return "hello, world"
}
println(sayHelloWorld())
// prints "hello, world"

盡管這個(gè)函數(shù)沒有參數(shù),但是定義中在函數(shù)名后還是需要一對(duì)圓括號(hào)。當(dāng)被調(diào)用時(shí),也需要在函數(shù)名后寫一對(duì)圓括號(hào)。

無返回值函數(shù)(Functions Without Return Values)

函數(shù)可以沒有返回值。下面是 sayHello 函數(shù)的另一個(gè)版本,叫 waveGoodbye,這個(gè)函數(shù)直接輸出String 值,而不是返回它:

func sayGoodbye(personName: String) {
    println("Goodbye, \(personName)!")
}
sayGoodbye("Dave")
// prints "Goodbye, Dave!"

因?yàn)檫@個(gè)函數(shù)不需要返回值,所以這個(gè)函數(shù)的定義中沒有返回箭頭(->)和返回類型。

注意: 嚴(yán)格上來說,雖然沒有返回值被定義,sayGoodbye 函數(shù)依然返回了值。沒有定義返回類型的函數(shù)會(huì)返回特殊的值,叫 Void。它其實(shí)是一個(gè)空的元組(tuple),沒有任何元素,可以寫成()。

被調(diào)用時(shí),一個(gè)函數(shù)的返回值可以被忽略:

func printAndCount(stringToPrint: String) -> Int {
    println(stringToPrint)
    return countElements(stringToPrint)
}
func printWithoutCounting(stringToPrint: String) {
    printAndCount(stringToPrint)
}
printAndCount("hello, world")
// prints "hello, world" and returns a value of 12
printWithoutCounting("hello, world")
// prints "hello, world" but does not return a value

第一個(gè)函數(shù) printAndCount,輸出一個(gè)字符串并返回 Int 類型的字符數(shù)。第二個(gè)函數(shù)printWithoutCounting調(diào)用了第一個(gè)函數(shù),但是忽略了它的返回值。當(dāng)?shù)诙€(gè)函數(shù)被調(diào)用時(shí),消息依然會(huì)由第一個(gè)函數(shù)輸出,但是返回值不會(huì)被用到。

注意: 返回值可以被忽略,但定義了有返回值的函數(shù)必須返回一個(gè)值,如果在函數(shù)定義底部沒有返回任何值,這將導(dǎo)致編譯錯(cuò)誤(compile-time error)。

多重返回值函數(shù)(Functions with Multiple Return Values)

你可以用元組(tuple)類型讓多個(gè)值作為一個(gè)復(fù)合值從函數(shù)中返回。

下面的這個(gè)例子中,count 函數(shù)用來計(jì)算一個(gè)字符串中元音,輔音和其他字母的個(gè)數(shù)(基于美式英語的標(biāo)準(zhǔn))。

func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {
    var vowels = 0, consonants = 0, others = 0
    for character in string {
        switch String(character).lowercaseString {
        case "a", "e", "i", "o", "u":
            ++vowels
        case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
          "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
            ++consonants
        default:
            ++others
        }
    }
    return (vowels, consonants, others)
}

你可以用 count 函數(shù)來處理任何一個(gè)字符串,返回的值將是一個(gè)包含三個(gè) Int 型值的元組(tuple):

let total = count("some arbitrary string!")
println("\(total.vowels) vowels and \(total.consonants) consonants")
// prints "6 vowels and 13 consonants"

需要注意的是,元組的成員不需要在函數(shù)中返回時(shí)命名,因?yàn)樗鼈兊拿忠呀?jīng)在函數(shù)返回類型中有了定義。

函數(shù)參數(shù)名稱(Function Parameter Names)

以上所有的函數(shù)都給它們的參數(shù)定義了參數(shù)名(parameter name):

func someFunction(parameterName: Int) {
    // function body goes here, and can use parameterName
    // to refer to the argument value for that parameter
}

但是,這些參數(shù)名僅在函數(shù)體中使用,不能在函數(shù)調(diào)用時(shí)使用。這種類型的參數(shù)名被稱作局部參數(shù)名(local parameter name),因?yàn)樗鼈冎荒茉诤瘮?shù)體中使用。

外部參數(shù)名(External Parameter Names)

有時(shí)候,調(diào)用函數(shù)時(shí),給每個(gè)參數(shù)命名是非常有用的,因?yàn)檫@些參數(shù)名可以指出各個(gè)實(shí)參的用途是什么。

如果你希望函數(shù)的使用者在調(diào)用函數(shù)時(shí)提供參數(shù)名字,那就需要給每個(gè)參數(shù)除了局部參數(shù)名外再定義一個(gè)外部參數(shù)名。外部參數(shù)名寫在局部參數(shù)名之前,用空格分隔。

func someFunction(externalParameterName localParameterName: Int) {
    // function body goes here, and can use localParameterName
    // to refer to the argument value for that parameter
}

注意: 如果你提供了外部參數(shù)名,那么函數(shù)在被調(diào)用時(shí),必須使用外部參數(shù)名。

以下是個(gè)例子,這個(gè)函數(shù)使用一個(gè)結(jié)合者(joiner)把兩個(gè)字符串聯(lián)在一起:

func join(s1: String, s2: String, joiner: String) -> String {
    return s1 + joiner + s2
}

當(dāng)你調(diào)用這個(gè)函數(shù)時(shí),這三個(gè)字符串的用途是不清楚的:

join("hello", "world", ", ")
// returns "hello, world"

為了讓這些字符串的用途更為明顯,我們?yōu)?nbsp;join 函數(shù)添加外部參數(shù)名:

func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String {
    return s1 + joiner + s2
}

在這個(gè)版本的 join 函數(shù)中,第一個(gè)參數(shù)有一個(gè)叫 string 的外部參數(shù)名和 s1 的局部參數(shù)名,第二個(gè)參數(shù)有一個(gè)叫 toString 的外部參數(shù)名和 s2 的局部參數(shù)名,第三個(gè)參數(shù)有一個(gè)叫 withJoiner 的外部參數(shù)名和 joiner 的局部參數(shù)名。

現(xiàn)在,你可以使用這些外部參數(shù)名以一種清晰地方式來調(diào)用函數(shù)了:

join(string: "hello", toString: "world", withJoiner: ", ")
// returns "hello, world"

使用外部參數(shù)名讓第二個(gè)版本的 join 函數(shù)的調(diào)用更為有表現(xiàn)力,更為通順,同時(shí)還保持了函數(shù)體是可讀的和有明確意圖的。

注意: 當(dāng)其他人在第一次讀你的代碼,函數(shù)參數(shù)的意圖顯得不明顯時(shí),考慮使用外部參數(shù)名。如果函數(shù)參數(shù)名的意圖是很明顯的,那就不需要定義外部參數(shù)名了。

簡寫外部參數(shù)名(Shorthand External Parameter Names)

如果你需要提供外部參數(shù)名,但是局部參數(shù)名已經(jīng)定義好了,那么你不需要寫兩次參數(shù)名。相反,只寫一次參數(shù)名,并用井號(hào)(#)作為前綴就可以了。這告訴 Swift 使用這個(gè)參數(shù)名作為局部和外部參數(shù)名。

下面這個(gè)例子定義了一個(gè)叫 containsCharacter 的函數(shù),使用井號(hào)(#)的方式定義了外部參數(shù)名:

func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
    for character in string {
        if character == characterToFind {
            return true
        }
    }
    return false
}

這樣定義參數(shù)名,使得函數(shù)體更為可讀,清晰,同時(shí)也可以以一個(gè)不含糊的方式被調(diào)用:

let containsAVee = containsCharacter(string: "aardvark", characterToFind: "v")
// containsAVee equals true, because "aardvark" contains a "v”

默認(rèn)參數(shù)值(Default Parameter Values)

你可以在函數(shù)體中為每個(gè)參數(shù)定義默認(rèn)值。當(dāng)默認(rèn)值被定義后,調(diào)用這個(gè)函數(shù)時(shí)可以忽略這個(gè)參數(shù)。

注意: 將帶有默認(rèn)值的參數(shù)放在函數(shù)參數(shù)列表的最后。這樣可以保證在函數(shù)調(diào)用時(shí),非默認(rèn)參數(shù)的順序是一致的,同時(shí)使得相同的函數(shù)在不同情況下調(diào)用時(shí)顯得更為清晰。

以下是另一個(gè)版本的join函數(shù),其中joiner有了默認(rèn)參數(shù)值:

func join(string s1: String, toString s2: String, withJoiner joiner: String = " ") -> String {
    return s1 + joiner + s2
}

像第一個(gè)版本的 join 函數(shù)一樣,如果 joiner 被賦值時(shí),函數(shù)將使用這個(gè)字符串值來連接兩個(gè)字符串:

join(string: "hello", toString: "world", withJoiner: "-")
// returns "hello-world"

當(dāng)這個(gè)函數(shù)被調(diào)用時(shí),如果 joiner 的值沒有被指定,函數(shù)會(huì)使用默認(rèn)值(" "):

join(string: "hello", toString:"world")
// returns "hello world"

默認(rèn)值參數(shù)的外部參數(shù)名(External Names for Parameters with Default Values)

在大多數(shù)情況下,給帶默認(rèn)值的參數(shù)起一個(gè)外部參數(shù)名是很有用的。這樣可以保證當(dāng)函數(shù)被調(diào)用且?guī)J(rèn)值的參數(shù)被提供值時(shí),實(shí)參的意圖是明顯的。

為了使定義外部參數(shù)名更加簡單,當(dāng)你未給帶默認(rèn)值的參數(shù)提供外部參數(shù)名時(shí),Swift 會(huì)自動(dòng)提供外部名字。此時(shí)外部參數(shù)名與局部名字是一樣的,就像你已經(jīng)在局部參數(shù)名前寫了井號(hào)(#)一樣。

下面是 join 函數(shù)的另一個(gè)版本,這個(gè)版本中并沒有為它的參數(shù)提供外部參數(shù)名,但是 joiner 參數(shù)依然有外部參數(shù)名:

func join(s1: String, s2: String, joiner: String = " ") -> String {
    return s1 + joiner + s2
}

在這個(gè)例子中,Swift 自動(dòng)為 joiner 提供了外部參數(shù)名。因此,當(dāng)函數(shù)調(diào)用時(shí),外部參數(shù)名必須使用,這樣使得參數(shù)的用途變得清晰。

join("hello", "world", joiner: "-")
// returns "hello-world"

注意: 你可以使用下劃線(_)作為默認(rèn)值參數(shù)的外部參數(shù)名,這樣可以在調(diào)用時(shí)不用提供外部參數(shù)名。但是給帶默認(rèn)值的參數(shù)命名總是更加合適的。

可變參數(shù)(Variadic Parameters)

一個(gè)可變參數(shù)(variadic parameter)可以接受一個(gè)或多個(gè)值。函數(shù)調(diào)用時(shí),你可以用可變參數(shù)來傳入不確定數(shù)量的輸入?yún)?shù)。通過在變量類型名后面加入(...)的方式來定義可變參數(shù)。

傳入可變參數(shù)的值在函數(shù)體內(nèi)當(dāng)做這個(gè)類型的一個(gè)數(shù)組。例如,一個(gè)叫做 numbers 的 Double... 型可變參數(shù),在函數(shù)體內(nèi)可以當(dāng)做一個(gè)叫 numbers 的 Double[] 型的數(shù)組常量。

下面的這個(gè)函數(shù)用來計(jì)算一組任意長度數(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, 19)
// returns 10.0, which is the arithmetic mean of these three numbers

注意: 一個(gè)函數(shù)至多能有一個(gè)可變參數(shù),而且它必須是參數(shù)表中最后的一個(gè)。這樣做是為了避免函數(shù)調(diào)用時(shí)出現(xiàn)歧義。

如果函數(shù)有一個(gè)或多個(gè)帶默認(rèn)值的參數(shù),而且還有一個(gè)可變參數(shù),那么把可變參數(shù)放在參數(shù)表的最后。

常量參數(shù)和變量參數(shù)(Constant and Variable Parameters)

函數(shù)參數(shù)默認(rèn)是常量。試圖在函數(shù)體中更改參數(shù)值將會(huì)導(dǎo)致編譯錯(cuò)誤。這意味著你不能錯(cuò)誤地更改參數(shù)值。

但是,有時(shí)候,如果函數(shù)中有傳入?yún)?shù)的變量值副本將是很有用的。你可以通過指定一個(gè)或多個(gè)參數(shù)為變量參數(shù),從而避免自己在函數(shù)中定義新的變量。變量參數(shù)不是常量,你可以在函數(shù)中把它當(dāng)做新的可修改副本來使用。

通過在參數(shù)名前加關(guān)鍵字 var 來定義變量參數(shù):

func alignRight(var string: String, count: Int, pad: Character) -> String {
    let amountToPad = count - countElements(string)
    for _ in 1...amountToPad {
        string = pad + string
    }
    return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"

這個(gè)例子中定義了一個(gè)新的叫做 alignRight 的函數(shù),用來右對(duì)齊輸入的字符串到一個(gè)長的輸出字符串中。左側(cè)空余的地方用指定的填充字符填充。這個(gè)例子中,字符串"hello"被轉(zhuǎn)換成了"-----hello"。

alignRight 函數(shù)將參數(shù) string 定義為變量參數(shù)。這意味著 string 現(xiàn)在可以作為一個(gè)局部變量,用傳入的字符串值初始化,并且可以在函數(shù)體中進(jìn)行操作。

該函數(shù)首先計(jì)算出多少個(gè)字符需要被添加到 string 的左邊,以右對(duì)齊到總的字符串中。這個(gè)值存在局部常量 amountToPad 中。這個(gè)函數(shù)然后將 amountToPad 多的填充(pad)字符填充到 string 左邊,并返回結(jié)果。它使用了 string 這個(gè)變量參數(shù)來進(jìn)行所有字符串操作。

注意: 對(duì)變量參數(shù)所進(jìn)行的修改在函數(shù)調(diào)用結(jié)束后便消失了,并且對(duì)于函數(shù)體外是不可見的。變量參數(shù)僅僅存在于函數(shù)調(diào)用的生命周期中。

輸入輸出參數(shù)(In-Out Parameters)

變量參數(shù),正如上面所述,僅僅能在函數(shù)體內(nèi)被更改。如果你想要一個(gè)函數(shù)可以修改參數(shù)的值,并且想要在這些修改在函數(shù)調(diào)用結(jié)束后仍然存在,那么就應(yīng)該把這個(gè)參數(shù)定義為輸入輸出參數(shù)(In-Out Parameters)。

定義一個(gè)輸入輸出參數(shù)時(shí),在參數(shù)定義前加 inout 關(guān)鍵字。一個(gè)輸入輸出參數(shù)有傳入函數(shù)的值,這個(gè)值被函數(shù)修改,然后被傳出函數(shù),替換原來的值。

你只能傳入一個(gè)變量作為輸入輸出參數(shù)。你不能傳入常量或者字面量(literal value),因?yàn)檫@些量是不能被修改的。當(dāng)傳入的參數(shù)作為輸入輸出參數(shù)時(shí),需要在參數(shù)前加&符,表示這個(gè)值可以被函數(shù)修改。

注意: 輸入輸出參數(shù)不能有默認(rèn)值,而且可變參數(shù)不能用 inout 標(biāo)記。如果你用 inout 標(biāo)記一個(gè)參數(shù),這個(gè)參數(shù)不能被 var 或者 let 標(biāo)記。

下面是例子,swapTwoInts 函數(shù),有兩個(gè)分別叫做 a 和 b 的輸入輸出參數(shù):

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

這個(gè) swapTwoInts 函數(shù)僅僅交換 a 與 b 的值。該函數(shù)先將 a 的值存到一個(gè)暫時(shí)常量 temporaryA中,然后將 b 的值賦給 a,最后將 temporaryA 幅值給 b。

你可以用兩個(gè) Int 型的變量來調(diào)用 swapTwoInts。需要注意的是,someInt 和 anotherInt 在傳入swapTwoInts 函數(shù)前,都加了 & 的前綴:

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3”

從上面這個(gè)例子中,我們可以看到 someInt 和 anotherInt 的原始值在 swapTwoInts 函數(shù)中被修改,盡管它們的定義在函數(shù)體外。

注意: 輸出輸出參數(shù)和返回值是不一樣的。上面的 swapTwoInts 函數(shù)并沒有定義任何返回值,但仍然修改了 someInt 和 anotherInt 的值。輸入輸出參數(shù)是函數(shù)對(duì)函數(shù)體外產(chǎn)生影響的另一種方式。

函數(shù)類型(Function Types)

每個(gè)函數(shù)都有種特定的函數(shù)類型,由函數(shù)的參數(shù)類型和返回類型組成。

例如:

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

這個(gè)例子中定義了兩個(gè)簡單的數(shù)學(xué)函數(shù):addTwoInts 和 multiplyTwoInts。這兩個(gè)函數(shù)都傳入兩個(gè)Int 類型, 返回一個(gè)合適的Int值。

這兩個(gè)函數(shù)的類型是 (Int, Int) -> Int,可以讀作“這個(gè)函數(shù)類型,它有兩個(gè) Int 型的參數(shù)并返回一個(gè)Int 型的值。”。

下面是另一個(gè)例子,一個(gè)沒有參數(shù),也沒有返回值的函數(shù):

func printHelloWorld() {
    println("hello, world")
}

這個(gè)函數(shù)的類型是:() -> (),或者叫“沒有參數(shù),并返回 Void 類型的函數(shù)”。沒有指定返回類型的函數(shù)總返回 Void。在Swift中,Void 與空的元組是一樣的。

使用函數(shù)類型(Using Function Types)

在 Swift 中,使用函數(shù)類型就像使用其他類型一樣。例如,你可以定義一個(gè)類型為函數(shù)的常量或變量,并將函數(shù)賦值給它:

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

這個(gè)可以讀作:

“定義一個(gè)叫做 mathFunction 的變量,類型是‘一個(gè)有兩個(gè) Int 型的參數(shù)并返回一個(gè) Int 型的值的函數(shù)’,并讓這個(gè)新變量指向 addTwoInts 函數(shù)”。

addTwoInts 和 mathFunction 有同樣的類型,所以這個(gè)賦值過程在 Swift 類型檢查中是允許的。

現(xiàn)在,你可以用 mathFunction 來調(diào)用被賦值的函數(shù)了:

println("Result: \(mathFunction(2, 3))")
// prints "Result: 5"

有相同匹配類型的不同函數(shù)可以被賦值給同一個(gè)變量,就像非函數(shù)類型的變量一樣:

mathFunction = multiplyTwoInts
println("Result: \(mathFunction(2, 3))")
// prints "Result: 6"

就像其他類型一樣,當(dāng)賦值一個(gè)函數(shù)給常量或變量時(shí),你可以讓 Swift 來推斷其函數(shù)類型:

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

函數(shù)類型作為參數(shù)類型(Function Types as Parameter Types)

你可以用(Int, Int) -> Int這樣的函數(shù)類型作為另一個(gè)函數(shù)的參數(shù)類型。這樣你可以將函數(shù)的一部分實(shí)現(xiàn)交由給函數(shù)的調(diào)用者。

下面是另一個(gè)例子,正如上面的函數(shù)一樣,同樣是輸出某種數(shù)學(xué)運(yùn)算結(jié)果:

func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
    println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// prints "Result: 8”

這個(gè)例子定義了 printMathResult 函數(shù),它有三個(gè)參數(shù):第一個(gè)參數(shù)叫 mathFunction,類型是(Int, Int) -> Int,你可以傳入任何這種類型的函數(shù);第二個(gè)和第三個(gè)參數(shù)叫 a 和 b,它們的類型都是 Int,這兩個(gè)值作為已給的函數(shù)的輸入值。

當(dāng) printMathResult 被調(diào)用時(shí),它被傳入 addTwoInts 函數(shù)和整數(shù)3和5。它用傳入3和5調(diào)用addTwoInts,并輸出結(jié)果:8。

printMathResult 函數(shù)的作用就是輸出另一個(gè)合適類型的數(shù)學(xué)函數(shù)的調(diào)用結(jié)果。它不關(guān)心傳入函數(shù)是如何實(shí)現(xiàn)的,它只關(guān)心這個(gè)傳入的函數(shù)類型是正確的。這使得 printMathResult 可以以一種類型安全(type-safe)的方式來保證傳入函數(shù)的調(diào)用是正確的。

函數(shù)類型作為返回類型(Function Type as Return Types)

你可以用函數(shù)類型作為另一個(gè)函數(shù)的返回類型。你需要做的是在返回箭頭(->)后寫一個(gè)完整的函數(shù)類型。

下面的這個(gè)例子中定義了兩個(gè)簡單函數(shù),分別是 stepForward 和stepBackward。stepForward 函數(shù)返回一個(gè)比輸入值大一的值。stepBackward 函數(shù)返回一個(gè)比輸入值小一的值。這兩個(gè)函數(shù)的類型都是(Int) -> Int:

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

下面這個(gè)叫做 chooseStepFunction 的函數(shù),它的返回類型是 (Int) -> Int 的函數(shù)。chooseStepFunction 根據(jù)布爾值 backwards 來返回 stepForward 函數(shù)或 stepBackward 函數(shù):

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

你現(xiàn)在可以用 chooseStepFunction 來獲得一個(gè)函數(shù),不管是那個(gè)方向:

var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function

上面這個(gè)例子中計(jì)算出從 currentValue 逐漸接近到0是需要向正數(shù)走還是向負(fù)數(shù)走。currentValue 的初始值是3,這意味著 currentValue > 0 是真的(true),這將使得 chooseStepFunction 返回stepBackward 函數(shù)。一個(gè)指向返回的函數(shù)的引用保存在了 moveNearerToZero 常量中。

現(xiàn)在,moveNearerToZero 指向了正確的函數(shù),它可以被用來數(shù)到0:

println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
    println("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// 3...
// 2...
// 1...
// zero!

嵌套函數(shù)(Nested Functions)

這章中你所見到的所有函數(shù)都叫全局函數(shù)(global functions),它們定義在全局域中。你也可以把函數(shù)定義在別的函數(shù)體中,稱作嵌套函數(shù)(nested functions)。

默認(rèn)情況下,嵌套函數(shù)是對(duì)外界不可見的,但是可以被他們封閉函數(shù)(enclosing function)來調(diào)用。一個(gè)封閉函數(shù)也可以返回它的某一個(gè)嵌套函數(shù),使得這個(gè)函數(shù)可以在其他域中被使用。

你可以用返回嵌套函數(shù)的方式重寫 chooseStepFunction 函數(shù):

func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backwards ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(currentValue < 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
    println("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

名稱欄目:2.6函數(shù)(Functions)-創(chuàng)新互聯(lián)
當(dāng)前鏈接:http://chinadenli.net/article28/edicp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計(jì)公司定制網(wǎng)站外貿(mào)網(wǎng)站建設(shè)面包屑導(dǎo)航網(wǎng)站維護(hù)小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)