Swift 函式

Swift 函式用來完成特定任務的獨立的程式碼塊。

Swift使用一個統一的語法來表示簡單的C語言風格的函式到複雜的Objective-C語言風格的方法。

  • 函式宣告: 告訴編譯器函式的名字,返回型別及引數。

  • 函式定義: 提供了函式的實體。

Swift 函式包含了引數型別及返回值型別:


函式定義

Swift 定義函式使用關鍵字 func

定義函式的時候,可以指定一個或多個輸入引數和一個返回值型別。

每個函式都有一個函式名來描述它的功能。通過函式名以及對應型別的引數值來呼叫這個函式。函式的引數傳遞的順序必須與引數列表相同。

函式的實參傳遞的順序必須與形參列表相同,-> 後定義函式的返回值型別。

語法

func funcname(形參) -> returntype
{
   Statement1
   Statement2
   ……
   Statement N
   return parameters
}

例項

以下我們定義了一個函式名為 itread01 的函式,形參的資料型別為 String,返回值也為 String:

import Cocoa

func itread01(site: String) -> String {
    return (site)
}
print(itread01(site: "www.itread01.com"))

以上程式執行輸出結果為:

www.itread01.com

函式呼叫

我們可以通過函式名以及對應型別的引數值來呼叫函式,函式的引數傳遞的順序必須與引數列表相同。

以下我們定義了一個函式名為 itread01 的函式,形參 site 的資料型別為 String,之後我們呼叫函式傳遞的實參也必須 String 型別,實參傳入函式體後,將直接返回,返回的資料型別為 String。

import Cocoa

func itread01(site: String) -> String {
    return (site)
}
print(itread01(site: "www.itread01.com"))

以上程式執行輸出結果為:

www.itread01.com

函式引數

函式可以接受一個或者多個引數,這些引數被包含在函式的括號之中,以逗號分隔。

以下例項向函式 itread01 傳遞站點名 name 和站點地址 site:

import Cocoa

func itread01(name: String, site: String) -> String {
    return name + site
}
print(itread01(name: "入門教學:", site: "www.itread01.com"))
print(itread01(name: "Google:", site: "www.google.com"))

以上程式執行輸出結果為:

入門教學:www.itread01.com
Google:www.google.com

不帶引數函式

我們可以建立不帶引數的函式。

語法:

func funcname() -> datatype {
   return datatype
}

例項

import Cocoa

func sitename() -> String {
    return "入門教學"
}
print(sitename())

以上程式執行輸出結果為:

入門教學

元組作為函式返回值

函式返回值型別可以是字串,整型,浮點型等。

元組與陣列類似,不同的是,元組中的元素可以是任意型別,使用的是圓括號。

你可以用元組(tuple)型別讓多個值作為一個複合值從函式中返回。

下面的這個例子中,定義了一個名為minMax(_:)的函式,作用是在一個Int陣列中找出最小值與最大值。

import Cocoa

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

let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("最小值為 \(bounds.min) ,最大值為 \(bounds.max)")

minMax(_:)函式返回一個包含兩個Int值的元組,這些值被標記為min和max,以便查詢函式的返回值時可以通過名字訪問它們。

以上程式執行輸出結果為:

最小值為 -6 ,最大值為 109

如果你不確定返回的元組一定不為nil,那麼你可以返回一個可選的元組型別。

你可以通過在元組型別的右括號後放置一個問號來定義一個可選元組,例如(Int, Int)?或(String, Int, Bool)?

注意
可選元組型別如(Int, Int)?與元組包含可選型別如(Int?, Int?)是不同的.可選的元組型別,整個元組是可選的,而不只是元組中的每個元素值。

前面的minMax(_:)函式返回了一個包含兩個Int值的元組。但是函式不會對傳入的陣列執行任何安全檢查,如果array引數是一個空陣列,如上定義的minMax(_:)在試圖訪問array[0]時會觸發一個執行時錯誤。

為了安全地處理這個"空陣列"問題,將minMax(_:)函式改寫為使用可選元組返回型別,並且當陣列為空時返回nil

import Cocoa

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)
}
if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
    print("最小值為 \(bounds.min),最大值為 \(bounds.max)")
}

以上程式執行輸出結果為:

最小值為 -6,最大值為 109

沒有返回值函式

下面是 itread01(_:) 函式的另一個版本,這個函式接收入門教學官網網址引數,沒有指定返回值型別,並直接輸出 String 值,而不是返回它:

import Cocoa

func itread01(site: String) {
    print("入門教學官網:\(site)")
}
itread01(site: "http://www.itread01.com")

以上程式執行輸出結果為:

入門教學官網:http://www.itread01.com

函式引數名稱

函式引數都有一個外部引數名和一個區域性引數名。

區域性引數名

區域性引數名在函式的實現內部使用。

func sample(number: Int) {
   println(number)
}

以上例項中 number 為區域性引數名,只能在函式體內使用。

import Cocoa

func sample(number: Int) {
    print(number)
}
sample(number: 1)
sample(number: 2)
sample(number: 3)

以上程式執行輸出結果為:

1
2
3

外部引數名

你可以在區域性引數名前指定外部引數名,中間以空格分隔,外部引數名用於在函式呼叫時傳遞給函式的引數。

如下你可以定義以下兩個函式引數名並呼叫它:

import Cocoa

func pow(firstArg a: Int, secondArg b: Int) -> Int {
   var res = a
   for _ in 1..<b {
      res = res * a
   }
   print(res)
   return res
}
pow(firstArg:5, secondArg:3)

以上程式執行輸出結果為:

125

注意
如果你提供了外部引數名,那麼函式在被呼叫時,必須使用外部引數名。


可變引數

可變引數可以接受零個或多個值。函式呼叫時,你可以用可變引數來指定函式引數,其數量是不確定的。

可變引數通過在變數型別名後面加入(...)的方式來定義。

import Cocoa

func vari<N>(members: N...){
    for i in members {
        print(i)
    }
}
vari(members: 4,3,5)
vari(members: 4.5, 3.1, 5.6)
vari(members: "Google", "Baidu", "itread01")

以上程式執行輸出結果為:

4
3
5
4.5
3.1
5.6
Google
Baidu
itread01

常量,變數及 I/O 引數

一般預設在函式中定義的引數都是常量引數,也就是這個引數你只可以查詢使用,不能改變它的值。

如果想要宣告一個變數引數,可以在引數定義前加 inout 關鍵字,這樣就可以改變這個引數的值了。

例如:

func  getName(_ name: inout String).........

此時這個 name 值可以在函式中改變。

一般預設的引數傳遞都是傳值呼叫的,而不是傳引用。所以傳入的引數在函式內改變,並不影響原來的那個引數。傳入的只是這個引數的副本。

當傳入的引數作為輸入輸出引數時,需要在引數名前加 & 符,表示這個值可以被函式修改。

例項

import Cocoa

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


var x = 1
var y = 5
swapTwoInts(&x, &y)
print("x 現在的值 \(x), y 現在的值 \(y)")

swapTwoInts(_:_:) 函式簡單地交換 a 與 b 的值。該函式先將 a 的值存到一個臨時常量 temporaryA 中,然後將 b 的值賦給 a,最後將 temporaryA 賦值給 b。

需要注意的是,someInt 和 anotherInt 在傳入 swapTwoInts(_:_:) 函式前,都加了 & 的字首。

以上程式執行輸出結果為:

x 現在的值 5, y 現在的值 1

函式型別及使用

每個函式都有種特定的函式型別,由函式的引數型別和返回型別組成。

func inputs(no1: Int, no2: Int) -> Int {
   return no1/no2
}

inputs 函式型別有兩個 Int 型的引數(no1、no2)並返回一個 Int 型的值。

例項如下:

import Cocoa

func inputs(no1: Int, no2: Int) -> Int {
    return no1/no2
}
print(inputs(no1: 20, no2: 10))
print(inputs(no1: 36, no2: 6))

以上程式執行輸出結果為:

2
6

以上函式定義了兩個 Int 引數型別,返回值也為 Int 型別。

接下來我們看下如下函式,函式定義了引數為 String 型別,返回值為 String 型別。

func inputstr(name: String) -> String {
   return name
}

函式也可以定義一個沒有引數,也沒有返回值的函式,如下所示:

import Cocoa

func inputstr() {
   print("入門教學")
   print("www.itread01.com")
}
inputstr()

以上程式執行輸出結果為:

入門教學
www.itread01.com

使用函式型別

在 Swift 中,使用函式型別就像使用其他型別一樣。例如,你可以定義一個型別為函式的常量或變數,並將適當的函式賦值給它:

var addition: (Int, Int) -> Int = sum

解析:

"定義一個叫做 addition 的變數,引數與返回值型別均是 Int ,並讓這個新變數指向 sum 函式"。

sumaddition 有同樣的型別,所以以上操作是合法的。

現在,你可以用 addition 來呼叫被賦值的函數了:

import Cocoa

func sum(a: Int, b: Int) -> Int {
   return a + b
}
var addition: (Int, Int) -> Int = sum
print("輸出結果: \(addition(40, 89))")

以上程式執行輸出結果為:

輸出結果: 129

函式型別作為引數型別、函式型別作為返回型別

我們可以將函式作為引數傳遞給另外一個引數:

import Cocoa

func sum(a: Int, b: Int) -> Int {
    return a + b
}
var addition: (Int, Int) -> Int = sum
print("輸出結果: \(addition(40, 89))")

func another(addition: (Int, Int) -> Int, a: Int, b: Int) {
    print("輸出結果: \(addition(a, b))")
}
another(addition: sum, a: 10, b: 20)

以上程式執行輸出結果為:

輸出結果: 129
輸出結果: 30

函式巢狀

函式巢狀指的是函式內定義一個新的函式,外部的函式可以呼叫函式內定義的函式。

例項如下:

import Cocoa

func calcDecrement(forDecrement total: Int) -> () -> Int {
   var overallDecrement = 0
   func decrementer() -> Int {
      overallDecrement -= total
      return overallDecrement
   }
   return decrementer
}
let decrem = calcDecrement(forDecrement: 30)
print(decrem())

以上程式執行輸出結果為:

-30