函數是用來完成特定任務的獨立代碼塊
Swift 統?的函數語法?夠靈活,可以?來表?任何函數,包括從最簡單的沒有參數名字的 C ?格函數,到復雜的帶局部和外部參數名的 Objective-C ?格函數。參數可以提供默
認值,以簡化函數調?。參數也可以既當做傳?參數,也當做傳出參數,也就是說,?旦函數執?結束,傳?的參數值可以被修改。
在 Swift 中,每個函數都有?種類型,包括函數的參數值類型和返回值類型。你可以把函數類型當做任何其他普通變量類型?樣處理,這樣就可以更簡單地把函數當做別的函數的
參數,也可以從其他函數中返回函數。函數的定義可以寫在在其他函數定義中,這樣可以在嵌套函數范圍內實現功能封裝。
1、函數的定義與調用
定義一個函數時,可以定義?個或多個有名字和類型的值,作為函數的輸?(稱為參數,parameters),也可以定義某種類型的值作為函數執?結束的輸出(稱為返回類型)。
每個函數有個函數名,?來描述函數執?的任務。要使??個函數時,你?函數名“調?”,并傳給它匹配的輸?值(稱作實參,arguments)。?個函數的實參必須與函數參數表?參數的順序?致。
~~~
//myAge myName就是參數標簽,可有可無,寫出來可以清楚的知道參數的意思,跟oc中一樣
//參數1 age 類型Int,參數2 name 類型String,返回值類型 String
func callFunc(myAge age : Int, myName name : String) -> String {
return "name:" + name + ",age:" + String(age)
}
print(callFunc(myAge: 25, myName: "dzl"))//這里直接輸出函數返回值
//name:dzl,age:25
//Program ended with exit code: 0
~~~
2、函數參數與返回值
函數參數與返回值在Swift中極為靈活。你可以定義任何類型的函數,包括從不帶參數的簡單函數到復雜的帶有表達性參數名和不同參數選項的復雜函數。
(1)無參函數
~~~
//下面這兩種形式都是無參,無返回值的函數,當沒有返回值時,可以指定返回值類型為Void,也可以省略不寫
func noParameter() -> Void {
print("no parametr, no return value")
}
func noParameter2() {
print("no parametr2, no return value")
}
noParameter()
noParameter2()
//no parametr, no return value
//no parametr2, no return value
~~~
(2)多重輸入參數,多參量函數(就是參數類型不一樣)
函數可以有多個參數,寫在圓括號中,用逗號分隔
~~~
//三個輸入參數
func multipleParameter(age : Int, name : String, sex : String) {
print("Person name is \(name), age is \(age), sex is \(sex)")
}
multipleParameter(22, name: "Tom", sex: "boy")
//Person name is Tom, age is 22, sex is boy
~~~
(3)多重返回值函數
可以?元組(tuple)類型讓多個值作為?個復合值從函數中返回。
~~~
func returnTuple(name : String, englishScore : Double, mathScore : Double, chineseScore : Double) -> (describe : String, averageScore : Double) {
return ("name is " + name + ",englishScore is " + String(englishScore) + ",mathScore is " + String(mathScore) + ",chineseScore is " + String(chineseScore), (mathScore + englishScore + chineseScore) / 3)
}
var receive = returnTuple("dzl", englishScore: 70, mathScore: 80, chineseScore: 90)
print("\(receive.describe), average is \(receive.1)") //兩種訪問元組元素的方式
//name is dzl,englishScore is 70.0,mathScore is 80.0,chineseScore is 90.0, average is 80.0
~~~
3、函數參數名稱
函數參數都有?個外部參數名(external parameter name)和?個本地參數名(local parameter name).外部參數名?來標記傳遞給函數調?的參數,本地參數名在實現函數的時
候使?
如(3)中例子
?般情況下,第?個參數省略其外部參數名,第?個以后的參數使?其本地參數名作為??的外部參數名.所有參數需要有不同的本地參數名,但可以共享相同的外部參數名
(1)指定外部參數名:
如1中例子
(2)忽略外部參數名:
如果你不想為第?個及后續的參數設置參數名,??個下劃線(_)代替?個明確地參數名
~~~
func ignoreParatemer(name : String, _ age : Int){
print("test ignore parameter, name is \(name), age is \(age)")
}
ignoreParatemer("dzl", 22)
//test ignore parameter, name is? dzl, age is 22
~~~
(3)默認參數值
可以在函數體中為每個參數定義 默認值(Deafult Values)? 。當默認值被定義后,調?這個函數時可以忽略這個參數
注意: 將帶有默認值的參數放在函數參數列表的最后。這樣可以保證在函數調?時,?默認參數的順序是?致的,同時使得相同的函數在不同情況下調?時顯得更為清晰
~~~
func defaultValue(name : String, englishScore : Double, mathScore : Double = 80.00, chineseScore : Double = 90.00) {
print("name is \(name), englishScore is \(englishScore), mathScore is \(mathScore), chineseScore is \(chineseScore)")
}
//三種調用方式
defaultValue("dzl", englishScore: 60)
defaultValue("dzl", englishScore: 65, mathScore: 81)
defaultValue("dzl", englishScore: 70, mathScore: 85, chineseScore: 95)
//三種輸出
name is dzl, englishScore is 60.0, mathScore is 80.0, chineseScore is 90.0
name is dzl, englishScore is 65.0, mathScore is 81.0, chineseScore is 90.0
name is dzl, englishScore is 70.0, mathScore is 85.0, chineseScore is 95.0
~~~
(4)可變參數
?個 可變參數(variadic parameter)? 可以接受零個或多個值。函數調?時,你可以?可變參數來傳?不確定數量的輸?參數。通過在變量類型名后?加? (...)? 的?式來定義可變參數。
~~~
func changeableParameter(scores : Double ...){
var totalScore : Double = 0
for score in scores {
totalScore += score
}
print("the average score is \(totalScore/Double(scores.count))")
}
changeableParameter(12.0, 34.0, 90.0, 32)
changeableParameter(65, 70)
//the average score is 42.0
//the average score is 67.5
~~~
(5)常量參數和變量參數
函數參數默認是常量。試圖在函數體中更改參數值將會導致編譯錯誤。這意味著你不能錯誤地更改參數值。
但是,有時候,如果函數中有傳?參數的變量值副本將是很有?的。你可以通過指定?個或多個參數為變量參數,從?避免??在函數中定義新的變量。變量參數不是常量,你可以在函數中把它當做新的可修改副本來使?。
通過在參數名前加關鍵字? var? 來定義變量參數:
~~~
func varParameter(var name : String, score : Double) {
name += (":" + String(score)) //可以修改name的值
print(name)
}
varParameter("dzl", score: 90)
//dzl:90.0
~~~
(6)輸入輸出參數
變量參數,正如上?所述,僅僅能在函數體內被更改。如果你想要?個函數可以修改參數的值,并且想要在這些修改在函數調?結束后仍然存在,那么就應該把這個參數定義為輸?輸出參數(In-Out Parameters)。
定義?個輸?輸出參數時,在參數定義前加? inout? 關鍵字。?個輸?輸出參數有傳?函數的值,這個值被函數修改,然后被傳出函數,替換原來的值。
你只能將變量作為輸?輸出參數。你不能傳?常量或者字?量(literal value),因為這些量是不能被修改的。當傳?的參數作為輸?輸出參數時,需要在參數前加 &? 符,表?這個值可以被函數修改。
注意: 輸?輸出參數不能有默認值,?且可變參數不能?? inout? 標記。如果你?inout? 標記?個參數,這個參數不能被? var? 或者? let? 標記。
~~~
func inoutParameter(inout a : Int, inout b : Int) {
let temp = a
a = b
b = temp
}
var a = 10
var b = 20
print("a is \(a), b is \(b)")
inoutParameter(&a, b: &b)
print("a is \(a), b is \(b)")
//a is 10, b is 20
//a is 20, b is 10
~~~
4、函數類型
每個函數都有種特定的函數類型,由函數的參數類型和返回類型組成
例如:
~~~
func addTwoInts(a: Int, _ b: Int) -> Int {
return a + b
}
func multiplyTwoInts(a: Int, _ b: Int) -> Int {
return a * b
}
~~~
這個例?中定義了兩個簡單的數學函數: addTwoInts? 和? multiplyTwoInts? 。這兩個函數都傳?兩個? Int? 類型, 返回?個合適的 Int? 值。
這兩個函數的類型是? (Int, Int) -> Int? ,可以讀作“這個函數類型,它有兩個? Int? 型的參數并返回?個? Int? 型的值。
下?是另?個例?,?個沒有參數,也沒有返回值的函數:
~~~
func printHelloWorld() {
print("hello, world")
}
~~~
這個函數的類型是: () -> void? ,或者叫“沒有參數,并返回? Void? 類型的函數”。
(1)使用函數類型
~~~
func useFuncType(a : Int, _ b : Int) -> Int {
return a + b
}
//定義?個叫做 varFuncType 的變量,類型是‘?個有兩個 Int 型的參數并返回?個 Int 型的值的函數’,并讓這個新變量指向 useFuncType 函數
var varFuncType : (Int, Int) -> Int = useFuncType
//然后我們就可以用varFuncType來調用useFuncType函數了
print(varFuncType(10, 20))
//還可以讓它自己推斷變量類型
var varFuncType2 = useFuncType
print(varFuncType2(100, 200))
//30
//300
~~~
(2)函數類型作為參數類型
~~~
func func1(a : Int, b : Int) -> Int {
return a + b
}
func func2(a : Int, b : Int) -> Int {
return a * b
}
func func3(funcParameter : (Int, Int) -> Int, a : Int, b : Int) {
let result = funcParameter(a, b)
print(result)
}
func3(func1, a: 10, b: 20)
func3(func2, a: 10, b: 20)
//30
//200
~~~
(3)函數類型作為返回值
~~~
func returnValue1(a : Int, b : Int) -> Int {
return a + b
}
func returnValue2(a : Int, b : Int) -> Int {
return a * b
}
func returnValue3(retFunc : Bool) -> (Int, Int) -> Int {
if retFunc {
return returnValue1
}else {
return returnValue2
}
}
print(returnValue3(true)(10, 20))
print(returnValue3(false)(10, 20))
//30
//200
~~~
5、嵌套函數
前面你所?到的所有函數都叫全局函數(global functions),它們定義在全局域中。你也可以把函數定義在別的函數體中,稱作嵌套函數(nested functions)
默認情況下,嵌套函數是對外界不可?的,但是可以被他們封閉函數(enclosing function)來調?。?個封閉函數也可以返回它的某?個嵌套函數,使得這個函數可以在其他域中被使?。
~~~
func returnValue13(retFunc : Bool) -> (Int, Int) -> Int {
//這兩個函數對外是不可見的,但是可以通過returnValue13 訪問
func returnValue11(a : Int, b : Int) -> Int {
return a + b
}
func returnValue12(a : Int, b : Int) -> Int {
return a * b
}
if retFunc {
return returnValue11
}else {
return returnValue12
}
}
print(returnValue13(true)(10, 20))
print(returnValue13(false)(10, 20))
//30
//200
~~~
- 前言
- swift控制語句,for,while,repeat-while,if,switch
- swift之聲明常量和變量
- swift之數值類型雜談(數值)
- swift之 元組
- oc與swift混編,OC調用swift,swift調用OC
- swift之可選類型
- swift之數組(Array)、集合(Set)、字典(Dictionary)
- swift之switch續(元組,值綁定,where)
- swift之控制轉移語句,continue,break,fallthrough,return,帶標簽的語句
- swift之函數(functions)
- swift之閉包(closure)
- swift之枚舉
- swift之類和結構體
- swift之屬性
- swift之方法(Methods)