Swift 函數


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

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

  • 函數宣告: 告訴編譯器函數的名字,傳回型別及參數。

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

Swift 函數包含了參數類型及傳回值類型:


#函數定義

Swift 定義函數使用關鍵字func

定義函數的時候,可以指定一個或多個輸入參數和一個回傳值類型。

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

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

語法

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

實例

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

import Cocoa

func php(site: String) -> String {
    return site
}
print(php("www.php.cn"))

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

www.php.cn

函數呼叫

#我們可以透過函數名稱以及對應類型的參數值來呼叫函數,函數的參數傳遞的順序必須與參數列表相同。

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

import Cocoa

func php(site: String) -> String {
    return site
}
print(php("www.php.cn"))

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

www.php.cn

函數參數

函數可以接受一個或多個參數,我們也可以使用元組(tuple)傳遞一個或多個參數給函數:

import Cocoa

func mult(no1: Int, no2: Int) -> Int {
   return no1*no2
}
print(mult(2, no2:20))
print(mult(3, no2:15))
print(mult(4, no2:30))

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

40
45
120

不帶參數函數

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

語法:

func funcname() -> datatype {
   return datatype
}

實例

import Cocoa

func sitename() -> String {
    return "php中文网"
}
print(sitename())

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

php中文网

元組作為函數傳回值

#函數傳回值型別可以是字串,整數型,浮點型等。

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

你可以用元組(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([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([8, -6, 2, 109, 3, 71]) {
    print("最小值为 \(bounds.min),组大值为 \(bounds.max)")
}

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

最小值为 -6,组大值为 109

沒有傳回值函數

下面是php(_:) 函數的另一個版本,這個函數接收php中文網官網址參數,沒有指定回傳值類型,直接輸出String 值,而不是回傳它:

import Cocoa

func php(site: String) {
    print("php中文网官网:\(site)")
}
php("http://www.php.cn")

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

php中文网官网:http://www.php.cn

函數參數名稱

函數參數都有一個外部參數名稱和一個局部參數名稱。

局部參數名稱

局部參數名稱在函數的實作內部使用。

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

以上實例中 number 為局部參數名,只能在函數體內使用。

import Cocoa

func sample(number: Int) {
   print(number)
}
sample(1)
sample(2)
sample(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(4,3,5)
vari(4.5, 3.1, 5.6)
vari("Google", "Baidu", "php")

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

4
3
5
4.5
3.1
5.6
Google
Baidu
php

常數,變數及I/O 參數

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

如果想要宣告一個變數參數,可以在前面加上var,這樣就可以改變這個參數的值了。

例如:

func  getName(var id:String).........

此時這個id值可以在函數中改變。

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

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

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

實例

import Cocoa

func swapTwoInts(var a:Int,var b:Int){
    
    let t = a
    a = b
    b = t
}

var x = 0,y = 100
print("x = \(x) ;y = \(y)")

swapTwoInts(x, b:y)
print("x = \(x) ;y = \(y)")

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

x = 0 ;y = 100
x = 0 ;y = 100
<p此時傳入的參數是原來值的副本,所以這個函數不會交換兩個值。 < p="">

修改方法是使用inout關鍵字:

import Cocoa

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

var x = 0,y = 100
print("x = \(x) ;y = \(y)")

swapTwoInts(&x, b:&y)
print("x = \(x) ;y = \(y)")

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

x = 0 ;y = 100
x = 100 ;y = 0

函數型別及使用

每個函數都有特定的函數類型,由函數的參數類型和傳回類型組成。

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

實例如下:

import Cocoa

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

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

2
6

以上函數定義了兩個 Int  參數類型,傳回值也為 Int 類型。

接下來我們看下如下函數,函數定義了參數為 String 類型,傳回值為 String 類型。

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

函數也可以定義任何參數及類型,如下所示:

import Cocoa

func inputstr() {
   print("php中文网")
   print("www.php.cn")
}
inputstr()

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

php中文网
www.php.cn

使用函數類型

在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(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