Swift教學
Swift快速入門
Swift簡介
Swift基礎
Swift常量和變量
Swift註釋
swift分號
Swift整數
Swift浮點數
Swift類型安全和類型推斷
swift數值型字面量
Swift數值型類型轉換
Swift類型別名
Swift布爾值
Swift元組
Swift可選類型
Swift斷言
Swift基本運算符
Swif哈希集合
Swift運算術語
Swift字典
Swift賦值運算符
Swift數值運算
Swift複合賦值
Swift比較運算
Swift三元條件運算
Swift區間運算符
Swift邏輯運算
Swift字符串和字符
Swift字符串字面量
Swift初始化空字符串
Swift字符串可變性
Swift字符串是值類型
Swift使用字符
Swift計算字符數量
Swift連接字符串和字符
Swift字符串插值
Swift比較字符串
Swift大寫和小寫字符串
Swift Unicode
Swift集合類型 (Collection Types)
Swift數組
Swift字典
Swift集合的可變性
Swift控制流
Swift For循環
Swift While循環
Swift條件語句
Swift控制轉移語句
Swift函數
Swift函數的定義與調用
Swift函數參數與返回值
Swift函數參數名稱
Swift函數類型
Swift嵌套函數
Swift閉包
Swift閉包表達式
Swift尾隨閉包
Swift捕獲值
Swift閉包是引用類型
Swift枚舉
Swift枚舉語法
Swift匹配枚舉值和Switch語句
Swift相關值
Swift原始值
Swift類和結構體
Swift類和結構體對比
Swift結構體和枚舉是值類型
Swift類是引用類型
Swift類和結構體的選擇
Swift集合(Collection)類型的賦值和拷貝行爲
Swift屬性
Swift存儲屬性
Swift計算屬性
Swift屬性監視器
Swift全局變量和局部變量
Swift類型屬性
Swift方法
Swift實例方法
Swift類型方法
Swift下標腳本
Swift下標腳本語法
Swift下標腳本用法
Swift下標腳本選項
Swift繼承
Swift定義一個基類
Swift子類生成
Swift重寫
Swift防止重寫
Swift構造過程
Swift存儲型屬性的初始賦值
Swift定製化構造過程
Swift默認構造器
Swift值類型的構造器代理
Swift類的繼承和構造過程
Swift通過閉包和函數來設置屬性的默認值
Swift析構過程
Swift析構過程原理
Swift析構函數操作
Swift自動引用計數
Swift自動引用計數的工作機制
Swift自動引用計數實踐
Swift類實例之間的循環強引用
Swift解決實例之間的循環強引用
Swift閉包引起的循環強引用
Swift解決閉包引起的循環強引用
Swift可選鏈
Swift可選鏈可替代強制解析
Swift爲可選鏈定義模型類
Swift通過可選鏈調用屬性
Swift通過可選鏈調用方法
Swift使用可選鏈調用子腳本
Swift連接多層鏈接
Swift鏈接可選返回值的方法
Swift類型轉換
Swift定義一個類層次作爲例子
Swift檢查類型
Swift向下轉型
Swift Any和AnyObject類型轉換
Swift嵌套類型
Swift嵌套類型實例
Swift嵌套類型的引用
Swift擴展
Swift擴展語法
Swift計算型屬性
Swift構造器
Swift方法擴展
Swift下標
Swift嵌套類型擴展
Swift協議
Swift協議的語法
Swift屬性要求
Swift方法要求
Swift突變方法要求
Swift協議類型
Swift委託(代理)模式
Swift在擴展中添加協議成員
Swift通過擴展補充協議聲明
Swift集合中的協議類型
Swift協議的繼承
Swift協議合成
Swift檢驗協議的一致性
Swift可選協議要求
Swift泛型
Swift泛型所解決的問題
Swift泛型函數
Swift類型參數
Swift命名類型參數
Swift泛型類型
Swift類型約束
Swift關聯類型
Swift Where語句
Swift高級運算符
Swift位運算符
Swift溢出運算符
Swift優先級和結合性
Swift運算符函數
Swift自定義運算符
Swift語法結構
Swift空白與註釋
Swift標識符
Swift關鍵字
Swift字面量
Swift運算符
Swift類型
Swift類型註解
Swift類型標識符
Swift元組類型
Swift函數類型(參數類型和返回值類型)
Swift數組類型
Swift可選類型(命名型類型)
Swift隱式解析可選類型
Swift協議合成類型
Swift元類型
Swift類型繼承子句
Swift類型推斷
Swift表達式
Swift前綴表達式
Swift二元表達式
Swift賦值表達式
Swift類型轉換運算符
Swift主表達式
Swift後綴表達式
Swift語句
Swift循環語句
Swift For語句
Swift分支語句
Swift帶標籤的語句
Swift聲明
Swift模塊範圍
Swift代碼塊
Swift引入聲明
Swift常量聲明
Swift類型的別名聲明
Swift函數聲明
Swift枚舉聲明
Swift結構體聲明
Swift類聲明
Swift協議聲明
Swift構造器聲明
Swift析構聲明
Swift擴展聲明
Swift下標腳本聲明
Swift運算符聲明
Swift變量聲明
Swift特性
Swift聲明特性
Swift類型特性
Swift模式
Swift通配符模式
Swift標識符模式
Swift值綁定模式
Swift元組模式
Swift枚舉用例模式
Swift類型轉換模式
Swift表達式模式
Swift泛型參數
Swift泛型形參子句
Swift開發環境設置
Swift基本語法
Swift數據類型
Swift變量
Swift常量
Swift字面量
Swift運算符
Swift比較運算符
Swift邏輯運算符
Swift位運算符
Swift賦值運算符
Swift範圍運算符
Swift其它運算符
Swift運算符優先級
Swift算術運算符
Swift if語句
Swift if...else語句
Swift if...else if...else語句
Swift嵌套 if 語句
Swift Switch語句
Swift決策
Swift for-in循環
Swift for循環
Swift while循環
Swift do...while循環
Swift continue語句
Swift break語句
Swift fallthrough語句
Swift循環
Swift字符串
Swift字符
Swift數組
Swift函數
Swift閉包
Swift枚舉
Swift結構體
Swift類
Swift 屬性
Swift 方法
Swift 下標
Swift 繼承
Swift初始化
Swift 反初始化
Swift ARC自動引用計數
Swift 可選鏈
Swift 類型轉換
Swift 擴展
Swift 協議
Swift 泛型
Swift訪問控制

Swift函數參數名稱

函數參數名稱(Function Parameter Names)

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

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

但是,這些參數名僅在函數體中使用,不能在函數調用時使用。這種類型的參數名被稱作局部參數名(local parameter name),因爲它們只能在函數體中使用。

外部參數名(External Parameter Names)

有時候,調用函數時,給每個參數命名是非常有用的,因爲這些參數名可以指出各個實參的用途是什麼。

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

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

注意:
如果你提供了外部參數名,那麼函數在被調用時,必須使用外部參數名。  

以下是個例子,這個函數使用一個結合者(joiner)把兩個字符串聯在一起:

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

當你調用這個函數時,這三個字符串的用途是不清楚的:

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

爲了讓這些字符串的用途更爲明顯,我們爲 join 函數添加外部參數名:

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

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

現在,你可以使用這些外部參數名以一種清晰地方式來調用函數了:

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

使用外部參數名讓第二個版本的 join 函數的調用更爲有表現力,更爲通順,同時還保持了函數體是可讀的和有明確意圖的。

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

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

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

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

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

這樣定義參數名,使得函數體更爲可讀,清晰,同時也可以以一個不含糊的方式被調用:

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

默認參數值(Default Parameter Values)

你可以在函數體中爲每個參數定義默認值。當默認值被定義後,調用這個函數時可以略去這個參數。

注意:
將帶有默認值的參數放在函數參數表的最後。這樣可以保證在函數調用時,非默認參數的順序是一致的,同時使得相同的函數在不同情況下調用時顯得更爲清晰。  

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

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

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

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

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

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

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

在大多數情況下,給帶默認值的參數起一個外部參數名是很有用的。這樣可以保證當函數被調用且帶默認值的參數被提供值時,實參的意圖是明顯的。

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

下面是 join 函數的另一個版本,這個版本中並沒有爲它的參數提供外部參數名,但是 joiner 參數依然有外部參數名:

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

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

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

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

可變參數(Variadic Parameters)

一個可變參數(variadic parameter)可以接受一個或多個值。函數調用時,你可以用可變參數來傳入不確定數量的輸入參數。通過在變量類型名後面加入(...)的方式來定義可變參數。

傳入可變參數的值在函數體內當做這個類型的一個數組。例如,一個叫做 numbers 的 Double... 型可變參數,在函數體內可以當做一個叫 numbers 的 Double[] 型的數組常量。

下面的這個函數用來計算一組任意長度數字的算術平均數:

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

注意:
一個函數至多能有一個可變參數,而且它必須是參數表中最後的一個。這樣做是爲了避免函數調用時出現歧義。  

如果函數有一個或多個帶默認值的參數,而且還有一個可變參數,那麼把可變參數放在參數表的最後。

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

函數參數默認是常量。試圖在函數體中更改參數值將會導致編譯錯誤。這意味着你不能錯誤地更改參數值。

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

通過在參數名前加關鍵字 var 來定義變量參數:

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"

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

alignRight 函數將參數 string 定義爲變量參數。這意味着 string 現在可以作爲一個局部變量,用傳入的字符串值初始化,並且可以在函數體中進行操作。

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

注意:
對變量參數所進行的修改在函數調用結束後便消失了,並且對於函數體外是不可見的。變量參數僅僅存在於函數調用的生命週期中。  

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

變量參數,正如上面所述,僅僅能在函數體內被更改。如果你想要一個函數可以修改參數的值,並且想要在這些修改在函數調用結束後仍然存在,那麼就應該把這個參數定義爲輸入輸出參數(In-Out Parameters)。

定義一個輸入輸出參數時,在參數定義前加 inout 關鍵字。一個輸入輸出參數有傳入函數的值,這個值被函數修改,然後被傳出函數,替換原來的值。

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

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

下面是例子,swapTwoInts 函數,有兩個分別叫做 a 和 b 的輸出輸出參數:

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

這個 swapTwoInts 函數僅僅交換 a 與 b 的值。該函數先將 a 的值存到一個暫時常量 temporaryA 中,然後將 b的值賦給 a,最後將 temporaryA 幅值給 b

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

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」

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

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