在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ 函數(shù)(Functions)
方法 - Methods
關(guān)于 Swift
下標腳本(Subscripts)
類和結(jié)構(gòu)體
類型轉(zhuǎn)換(Type Casting)
控制流
析構(gòu)過程(Deinitialization)
集合類型 (Collection Types)
構(gòu)造過程(Initialization)
Optional Chaining
枚舉(Enumerations)
自動引用計數(shù)
繼承(Inheritance)
擴展(Extensions)
泛型
字符串和字符(Strings and Characters)
函數(shù)(Functions)
高級運算符
訪問控制
基本運算符
嵌套類型
閉包(Closures)
協(xié)議
屬性 (Properties)

函數(shù)(Functions)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

為了簡化這個函數(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ù),包括從只帶一個未名參數(shù)的簡單函數(shù)到復(fù)雜的帶有表達性參數(shù)名和不同參數(shù)選項的復(fù)雜函數(shù)。

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

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

下面這個函數(shù)用一個半開區(qū)間的開始點和結(jié)束點,計算出這個范圍內(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ù)。下面這個函數(shù)就是一個無參函數(shù),當被調(diào)用時,它返回固定的 String 消息:

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

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

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

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

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

因為這個函數(shù)不需要返回值,所以這個函數(shù)的定義中沒有返回箭頭(->)和返回類型。

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

被調(diào)用時,一個函數(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

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

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

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

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

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

    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ù)來處理任何一個字符串,返回的值將是一個包含三個 Int 型值的元組(tuple):

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

需要注意的是,元組的成員不需要在函數(shù)中返回時命名,因為它們的名字已經(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ù)名(local parameter name),因為它們只能在函數(shù)體中使用。

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

有時候,調(diào)用函數(shù)時,給每個參數(shù)命名是非常有用的,因為這些參數(shù)名可以指出各個實參的用途是什么。

如果你希望函數(shù)的使用者在調(diào)用函數(shù)時提供參數(shù)名字,那就需要給每個參數(shù)除了局部參數(shù)名外再定義一個外部參數(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ù)使用一個結(jié)合者(joiner)把兩個字符串聯(lián)在一起:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

當這個函數(shù)被調(diào)用時,如果 joiner 的值沒有被指定,函數(shù)會使用默認值(" "):

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

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

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

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

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

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

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

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

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

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

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

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

下面的這個函數(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, 19)
    // returns 10.0, which is the arithmetic mean of these three numbers

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

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

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

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

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

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

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

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

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

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

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

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

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

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

你只能將變量作為輸入輸出參數(shù)。你不能傳入常量或者字面量(literal value),因為這些量是不能被修改的。當傳入的參數(shù)作為輸入輸出參數(shù)時,需要在參數(shù)前加&符,表示這個值可以被函數(shù)修改。

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

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

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

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

你可以用兩個 Int 型的變量來調(diào)用 swapTwoInts。需要注意的是,someIntanotherInt 在傳入 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”

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

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

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

每個函數(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ù):addTwoIntsmultiplyTwoInts。這兩個函數(shù)都傳入兩個 Int 類型, 返回一個合適的Int值。

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

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

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

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

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

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

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

這個可以讀作:

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

addTwoIntsmathFunction 有同樣的類型,所以這個賦值過程在 Swift 類型檢查中是允許的。

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

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

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

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

就像其他類型一樣,當賦值一個函數(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ù)類型作為另一個函數(shù)的參數(shù)類型。這樣你可以將函數(shù)的一部分實現(xiàn)交由給函數(shù)的調(diào)用者。

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

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

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

printMathResult 被調(diào)用時,它被傳入 addTwoInts 函數(shù)和整數(shù)35。它用傳入35調(diào)用 addTwoInts,并輸出結(jié)果:8。

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

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

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

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

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

下面這個叫做 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 來獲得一個函數(shù),不管是那個方向:

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

上面這個例子中計算出從 currentValue 逐漸接近到0是需要向正數(shù)走還是向負數(shù)走。currentValue 的初始值是3,這意味著 currentValue > 0 是真的(true),這將使得 chooseStepFunction 返回 stepBackward 函數(shù)。一個指向返回的函數(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)。

默認情況下,嵌套函數(shù)是對外界不可見的,但是可以被他們封閉函數(shù)(enclosing function)來調(diào)用。一個封閉函數(shù)也可以返回它的某一個嵌套函數(shù),使得這個函數(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!
上一篇:訪問控制下一篇:繼承(Inheritance)