## Swift 函數
Swift 中函數是引用類型。
### 函數語法
```
func 函數名 ( 參數變量: 類型 , 參數變量: 類型 ... ) -> 函數返回值 {
}
```
> 說明:
> 1: func 是定義函數的關鍵字
> 2:`{}` 函數體
> 3: 參數變量是默認常量類型,不能在函數函數體里面直接修改。即: `func A (value:String)` 與 `func A (let value:String)` 寫法是相同的,即 `value` 是常量。
### 函數中使用元組返回多個值
```
func findMaxAndMin( numbers: [Int])->( max: Int, min: Int )? {
guard numbers.count > 0 else {
return nil
}
var minValue = numbers[0]
var maxValue = numbers[0]
for number in numbers{
minValue = minValue < number ? minValue : number
maxValue = maxValue > number ? maxValue : number
}
return ( maxValue, minValue )
}
var scores: [Int]? = [202,1232,4321,33,432,666]
scores = scores ?? []
if let resault = findMaxAndMin(numbers:scores!){
print("The max score is \(resault.max)")
print("The min score is \(resault.min)")
}
```
### 函數的多個參數處理
#### 函數內部參數與外部參數
```
func sayHello( to name: String , message greeting: String ) -> String {
return "\(name),\(greeting)"
}
sayHello(to: "Curder", message: "Hello!!!")
```
> 內部參數有 `to` 與 `message`
> 外部參數有 `name` 與 `greeting`
#### 函數省略外部參數名
```
func mutiply( _ num1: Int, _ num2: Int ) -> Int{
return num1 * num2
}
mutiply(1, 2)
```
### 函數默認參數
```
func sayHello(to name: String, message greeting: String = "Hello",punctuation: String = "!")->String{
return "\(greeting),\(name)\(punctuation)"
}
// 調用省略可選參數
sayHello(to: "Luo") // "Hello,Luo!"
sayHello(to: "Luo",message: "Hi") // "Hi,Luo!"
sayHello(to: "Curder",punctuation: "!!!") // "Hello,Curder!!!"
sayHello(to: "Curder",message: "Hi",punctuation:"!!!") // "Hi,Curder!!!"
```
### 函數可變參數
在聲明函數的形參的時候 后面加上 `...`,在函數中,將該變長參數的值作為數組看待即可。
```
func mean( numbers: Double ... )->Double{
var sum: Double = 0
// 將變長的參數的值作為數組看待
for number in numbers{
sum += number
}
return sum / Double(numbers.count)
}
mean(numbers: 2)
mean(numbers: 2,3,4)
```
> 對于一個函數而言,只能有一個變長的參數。
### inout參數
函數的參數默認是 `let` 常量類型,我們不能在函數內部對傳入的參數進行修改,在Swift3.0中,可以在函數內部使用 `var` 聲明函數參數為變量進行修改。
```
func toBinary(num: Int) -> String {
var num = num // 需要將傳入的變量定義為 `var` 變量
var res = ""
repeat {
res = String(num%2) + res
num /= 2
} while num != 0
return res
}
toBinary(num: 100)
```
參數的地址引用,使用`inout`關鍵字
```
func swapTwoInts( _ a: inout Int, _ b:inout Int) {
let t:Int = a
a = b
b = t
}
var x: Int = 1
var y: Int = 2
swapTwoInts(&x, &y) // 使用 & 按引用傳遞
x // 2
y // 1
```
上面的函數也可以使用Swift中的元組實現。
```
func swapTwoInts2( _ a:inout Int, _ b:inout Int){
(a, b) = (b, a)
}
var x: Int = 1
var y: Int = 2
swapTwoInts2(&x, &y)
x // 2
y // 1
```
按值傳遞的數組
```
func initArray(arr: inout [Int], by value: Int) {
for i in 0..<arr.count {
arr[i] = value
}
}
var arr = [1, 2, 3, 4, 5]
initArray(arr: &arr, by: 0) // 需要使用 & 取地址符傳遞數據,改變原數組的值 [0, 0, 0, 0, 0]
```
### 聲明函數型變量
如果函數存在返回值的情況
```
func add(_ a: Int,_ b: Int)-> Int{
return a + b
}
let anotherAdd: (Int, Int) -> Int = add
anotherAdd(1,2)
```
> 上面的操作將 `add()` 函數直接賦值給 `anotherAdd()`,那么 `anotherAdd` 也是一個函數。
如果函數不存在返回值的清空
```
func sayHello(to name: String) -> Void{
print("Hello \(name)")
}
let anotherSayHello: (String)->Void = sayHello
// 或者這樣聲明函數常量
let anotherSayHello: (String)->() = sayHello
```
如果函數返回值和參數都不存在的情況,可以顯式的定義 `->Void`的方式定義。
```
func say(){
print("Hello!")
}
let anotherSay: ()->() = say
let anotherSay2: (Void)->Void = say
let anotherSay3: ()->Void = say
let anotherSay4: (Void)->() = say
```
> 就是 `Void` 和`()` 都可以表示返回值為空的情況。
#### 函數型變量的應用
使用系統函數`sorted()` 傳入函數型變量,對數組中的元素進行從大到小的排序
```
var arr: [Int] = []
for _ in 0..<100 {
arr.append(Int(arc4random() % 1000))
}
arr.sorted() // 不改變原有數組的值進行從小到大排序
arr.sort() // 改變有數組的值進行從小到大排序
// 那么我們想數組從大到小排序要怎么做呢?
arr.sorted(by: biggerNumberFirst) // 使用函數型變量傳值給參數
func biggerNumberFirst (a: Int, _ b: Int) -> Bool {
// if a > b {
// return true
// } else {
// return false
// }
return a > b // 可以直接使用運算符簡化上面的寫法
}
```
根據字符串排序
```
func cmpByNumberString(a: Int, _ b: Int) -> Bool {
return String(a) < String(b)
}
arr.sorted(by: cmpByNumberString) // [101, 105, 116, 129, 131, 142, 142, 146, 182, 183, 184, 187, 189, 197, 206, 207, 207, 229, 23, 240, 252, 253, 255, 262, 291, 295, 295, 32, 33, 377, 38, 395, 398, 422, 439, 450, 458, 464, 470, 475, 485, 488, 488, 494, 503, 505, 509, 518, 572, 573, 58, 584, 598, 6, 605, 615, 616, 619, 622, 624, 625, 633, 638, 647, 649, 655, 674, 680, 685, 713, 746, 746, 756, 757, 771, 771, 787, 789, 790, 791, 792, 792, 794, 806, 818, 836, 844, 864, 868, 880, 880, 888, 898, 902, 922, 944, 947, 960, 962, 99]
```
#### 返回函數類型和函數嵌套
```
// 計費方式1
func tierMailFeeByWeight(weight: Int) -> Int {
return 1 * weight
}
// 計費方式2
func tier2MailFeeByWeight(weight: Int) -> Int {
return 3 * weight
}
// 函數嵌套的應用
func feeByUnitPrice(price: Int, weight: Int) -> Int {
// 判斷計費方式 將函數作為返回值的用法
func chooseMailFeeCalculationByWeight(weight: Int) -> (Int) -> Int {
return weight <= 10 ? tierMailFeeByWeight : tier2MailFeeByWeight
}
let mailFeeByWeight = chooseMailFeeCalculationByWeight(weight: weight)
return mailFeeByWeight(weight) + price * weight
}
```
- 學習筆記
- 基礎
- 基本類型之整型
- 基本類型之浮點型
- 基本類型之布爾類型以及簡單的 if 語句
- 基礎類型之元組
- 基本類型之其他
- 運算符
- 基礎運算符
- 比較運算符、邏輯運算符
- 三元運算符
- 范圍運算符for-in
- 邏輯控制
- 循環結構
- 選擇結構
- 字符串
- Character和Unicode
- String.index 和 range
- 可選型
- 容器類
- 數組初始化
- 數組基本操作
- 字典初始化
- 字典基本操作
- 集合初始化
- 集合基本操作
- 函數
- 閉包
- 枚舉
- 結構體
- 類
- 文檔注釋
- 屬性和方法
- 下標和運算符重載
- 拓展和泛型
- 協議
- 其他
- Swift 3.0 For 循環
- Swift 隨機數的生成
- IOS開發玩轉界面 UIKit
- UILable 文本顯示控件
- UIButton 簡單的交互控件
- UIImageView 圖片控件
- UISearchBar 搜索控件