# Swift 函數
Swift 函數用來完成特定任務的獨立的代碼塊。
Swift使用一個統一的語法來表示簡單的C語言風格的函數到復雜的Objective-C語言風格的方法。
* 函數聲明: 告訴編譯器函數的名字,返回類型及參數。
* 函數定義: 提供了函數的實體。
Swift 函數包含了參數類型及返回值類型:
## 函數定義
Swift 定義函數使用關鍵字 **func**。
定義函數的時候,可以指定一個或多個輸入參數和一個返回值類型。
每個函數都有一個函數名來描述它的功能。通過函數名以及對應類型的參數值來調用這個函數。函數的參數傳遞的順序必須與參數列表相同。
函數的實參傳遞的順序必須與形參列表相同,**->** 后定義函數的返回值類型。
### 語法
```
func funcname(形參) -> returntype
{
Statement1
Statement2
……
Statement N
return parameters
}
```
### 實例
以下我們定義了一個函數名為 runoob 的函數,形參的數據類型為 String,返回值也為 String:
```
import Cocoa
func runoob(site: String) -> String {
return site
}
print(runoob("www.runoob.com"))
```
以上程序執行輸出結果為:
```
www.runoob.com
```
## 函數調用
我們可以通過函數名以及對應類型的參數值來調用函數,函數的參數傳遞的順序必須與參數列表相同。
以下我們定義了一個函數名為 runoob 的函數,形參 site 的數據類型為 String,之后我們調用函數傳遞的實參也必須 String 類型,實參傳入函數體后,將直接返回,返回的數據類型為 String。
```
import Cocoa
func runoob(site: String) -> String {
return site
}
print(runoob("www.runoob.com"))
```
以上程序執行輸出結果為:
```
www.runoob.com
```
## 函數參數
函數可以接受一個或者多個參數,我們也可以使用元組(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 "菜鳥教程"
}
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([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
```
## 沒有返回值函數
下面是 runoob(_:) 函數的另一個版本,這個函數接收菜鳥教程官網網址參數,沒有指定返回值類型,并直接輸出 String 值,而不是返回它:
```
import Cocoa
func runoob(site: String) {
print("菜鳥教程官網:\(site)")
}
runoob("http://www.runoob.com")
```
以上程序執行輸出結果為:
```
菜鳥教程官網:http://www.runoob.com
```
## 函數參數名稱
函數參數都有一個外部參數名和一個局部參數名。
### 局部參數名
局部參數名在函數的實現內部使用。
```
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", "Runoob")
```
以上程序執行輸出結果為:
```
4
3
5
4.5
3.1
5.6
Google
Baidu
Runoob
```
## 常量,變量及 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("菜鳥教程")
print("www.runoob.com")
}
inputstr()
```
以上程序執行輸出結果為:
```
菜鳥教程
www.runoob.com
```
### 使用函數類型
在 Swift 中,使用函數類型就像使用其他類型一樣。例如,你可以定義一個類型為函數的常量或變量,并將適當的函數賦值給它:
```
var addition: (Int, Int) -> Int = sum
```
解析:
"定義一個叫做 `addition` 的變量,參數與返回值類型均是 `Int` ,并讓這個新變量指向 `sum` 函數"。
`sum` 和 `addition` 有同樣的類型,所以以上操作是合法的。
現在,你可以用 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
```
- Swift 簡介
- Swift 環境搭建
- Swift 基本語法
- Swift 數據類型
- Swift 變量
- Swift 可選(Optionals)類型
- 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 repeat...while 循環
- Swift Continue 語句
- Swift Break 語句
- Swift Fallthrough 語句
- Swift 字符串
- Swift 字符(Character)
- Swift 數組
- Swift 字典
- Swift 函數
- Swift 閉包
- Swift 枚舉
- Swift 結構體
- Swift 類
- Swift 屬性
- Swift 方法
- Swift 下標腳本
- Swift 繼承
- Swift 構造過程
- Swift 析構過程
- Swift 可選鏈
- Swift 自動引用計數(ARC)
- Swift 類型轉換
- Swift 擴展
- Swift 協議
- Swift 泛型
- Swift 訪問控制