函數(shù)是一段完成特定任務的獨立代碼片段冷冗。你可以通過給函數(shù)命名來標識某個函數(shù)的功能,這個名字可以被用來在需要的時候"調(diào)用"這個函數(shù)來完成它的任務话浇。
Swift
統(tǒng)一的函數(shù)語法非常的靈活,可以用來表示任何函數(shù),包括從最簡單的沒有參數(shù)名字的 C
風格函數(shù)乡翅,到復雜的帶局部和外部參數(shù)名的 Objective-C
風格函數(shù)。參數(shù)可以提供默認值罪郊,以簡化函數(shù)調(diào)用蠕蚜。參數(shù)也可以既當做傳入?yún)?shù),也當做傳出參數(shù)悔橄,也就是說靶累,一旦函數(shù)執(zhí)行結(jié)束,傳入的參數(shù)值將被修改癣疟。
在 Swift
中挣柬,每個函數(shù)都有一個由函數(shù)的參數(shù)值類型和返回值類型組成的類型。你可以把函數(shù)類型當做任何其他普通變量類型一樣處理睛挚,這樣就可以更簡單地把函數(shù)當做別的函數(shù)的參數(shù)邪蛔,也可以從其他函數(shù)中返回函數(shù)。函數(shù)的定義可以寫在其他函數(shù)定義中扎狱,這樣可以在嵌套函數(shù)范圍內(nèi)實現(xiàn)功能封裝
函數(shù)的定義與調(diào)用
//帶參數(shù)侧到,帶返回值
func sum(x : Int, y : Int) -> Int {
return (x + y)
}
print(sum(x: 10, y: 10))
//帶參數(shù),帶返回值 元組
func maxAndMin(dataArr : [Int]) -> (maxInt:Int,minInt:Int) {
var currentMin = dataArr[0]
var currentMax = dataArr[0]
for value in dataArr[1..<dataArr.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
print(maxAndMin(dataArr: [5,7,3,4,9,7,1,6]))
//可選返回類型
func max(dataArr : [Int]) -> Int? {
var currentMin = dataArr[0]
for value in dataArr[1..<dataArr.count] {
if value < currentMin {
currentMin = value
}
}
return currentMin
}
if let min = max(dataArr: [5,7,3,4,9,7,2,6]){
print(min)
}else{
print("沒有返回有效值")
}
//可選返回類型 元組
func maxAndMinOption(dataArr : [Int]) -> (maxInt:Int,minInt:Int)? {
var currentMin = dataArr[0]
var currentMax = dataArr[0]
for value in dataArr[1..<dataArr.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
let dataA:[Int] = [5,7,3,4,9,7,2,6]
if let (maxInt,minInt) = maxAndMinOption(dataArr: dataA){
print(maxInt,minInt)
}else{
print("沒有返回有效值")
}
函數(shù)的參數(shù)標簽和參數(shù)名稱
每個函數(shù)參數(shù)都有一個參數(shù)標簽( argument label )
以及一個參數(shù)名稱( parameter name )
淤击。參數(shù)標簽在調(diào)用函數(shù)的時候使用匠抗;調(diào)用的時候需要將函數(shù)的參數(shù)標簽寫在對應的參數(shù)前面。參數(shù)名稱在函數(shù)的實現(xiàn)中使用遭贸。默認情況下戈咳,函數(shù)參數(shù)使用參數(shù)名稱來作為它們的參數(shù)標簽
/函數(shù)的參數(shù)標簽和參數(shù)名稱
//默認情況下,函數(shù)參數(shù)使用參數(shù)名稱來作為它們的參數(shù)標簽
func getString(inputStr:String) -> String {
return "hello" + inputStr
}
print(getString(inputStr: "Edison"))
//指定參數(shù)標簽
func getName(youEnglishName name: String) -> String {
return name + "hello"
}
print(getName(youEnglishName: "Edison"))
//忽略參數(shù)標簽
func getAgeDes(_ age : Int) -> String {
return "your age is" + String(age)
}
print(getAgeDes(14))
默認參數(shù)值
你可以在函數(shù)體中通過給參數(shù)賦值來為任意一個參數(shù)定義默認值(Deafult Value
)壕吹。當默認值被定義后著蛙,調(diào)用這個函數(shù)時可以忽略這個參數(shù)
func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
// 如果你在調(diào)用時候不傳第二個參數(shù),parameterWithDefault 會值為 12 傳入到函數(shù)體中耳贬。
}
someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6) // parameterWithDefault = 6
someFunction(parameterWithoutDefault: 4) // parameterWithDefault = 12
將不帶有默認值的參數(shù)放在函數(shù)參數(shù)列表的最前踏堡。一般來說,沒有默認值的參數(shù)更加的重要咒劲,將不帶默認值的參數(shù)放在最前保證在函數(shù)調(diào)用時顷蟆,非默認參數(shù)的順序是一致的,同時也使得相同的函數(shù)在不同情況下調(diào)用時顯得更為清晰
可變參數(shù)
一個可變參數(shù)(variadic parameter
)可以接受零個或多個值腐魂。函數(shù)調(diào)用時帐偎,你可以用可變參數(shù)來指定函數(shù)參數(shù)可以被傳入不確定數(shù)量的輸入值。通過在變量類型名后面加入(...)
的方式來定義可變參數(shù)蛔屹。
可變參數(shù)的傳入值在函數(shù)體中變?yōu)榇祟愋偷囊粋€數(shù)組削樊。例如,一個叫做numbers
的 Double...
型可變參數(shù),在函數(shù)體內(nèi)可以當做一個叫numbers
的[Double]
型的數(shù)組常量
func avg(dataAll: Double...) -> Double {
var total : Double = 0
for num in dataAll {
total += num
}
return total/Double(dataAll.count)
}
print(avg(dataAll: 1,2,3,4,5,6,7,8,9))
輸入輸出參數(shù)
函數(shù)參數(shù)默認是常量漫贞。試圖在函數(shù)體中更改參數(shù)值將會導致編譯錯誤(compile-time error)
甸箱。這意味著你不能錯誤地更改參數(shù)值。如果你想要一個函數(shù)可以修改參數(shù)的值迅脐,并且想要在這些修改在函數(shù)調(diào)用結(jié)束后仍然存在芍殖,那么就應該把這個參數(shù)定義為輸入輸出參數(shù)(In-Out Parameters)
。
定義一個輸入輸出參數(shù)時谴蔑,在參數(shù)定義前加 inout
關鍵字豌骏。一個輸入輸出參數(shù)有傳入函數(shù)的值,這個值被函數(shù)修改隐锭,然后被傳出函數(shù)肯适,替換原來的值。想獲取更多的關于輸入輸出參數(shù)的細節(jié)和相關的編譯器優(yōu)化成榜,請查看輸入輸出參數(shù)一節(jié)框舔。
你只能傳遞變量給輸入輸出參數(shù)。你不能傳入常量或者字面量赎婚,因為這些量是不能被修改的刘绣。當傳入的參數(shù)作為輸入輸出參數(shù)時,需要在參數(shù)名前加 &
符挣输,表示這個值可以被函數(shù)修改
//輸入輸出參數(shù)
func swapValue(valueA: inout Int,valueB : inout Int){
let valueTemp = valueA
valueA = valueB
valueB = valueTemp
}
var value1 = 11
var value2 = 22
swapValue(valueA: &value1, valueB: &value2)
print("new 1:\(value1),new 2:\(value2)")
函數(shù)類型
每個函數(shù)都有種特定的函數(shù)類型纬凤,函數(shù)的類型由函數(shù)的參數(shù)類型和返回類型組成。
func swapValue(valueA: inout Int,valueB : inout Int)
的類型: (Int:Int)-> Int
func swapValue2()
的類型: () -> Void
使用函數(shù)類型
在 Swift
中撩嚼,使用函數(shù)類型就像使用其他類型一樣停士。例如,你可以定義一個類型為函數(shù)的常量或變量完丽,并將適當?shù)暮瘮?shù)賦值給它:
//使用函數(shù)類型
func addTwoInts(_ a: Int, _ b: Int) -> Int {
return a + b
}
var addTest : (Int,Int)->Int = addTwoInts
print("\(addTest(2,3))")
嵌套函數(shù)
到目前為止恋技,本章節(jié)我們所見到的函數(shù)都稱之為全局函數(shù)(global functions)
,他們定義在全局域中逻族,你可以把函數(shù)定義在別的函數(shù)體中蜻底,稱之為嵌套函數(shù)(nested functions)
默認情況下,嵌套函數(shù)是對外界不可見的聘鳞,但是可以被它們的外圍函數(shù)(enclosing function)
調(diào)用薄辅。一個外圍函數(shù)也可以返回它的某一個嵌套函數(shù),使得這個函數(shù)可以在其他域中被使用抠璃。
// 嵌套函數(shù)
func moreFun(x : Int , y : Int) -> Int {
func func1(p1 : Int) -> Int{
return p1 + 10
}
func func2(p2 : Int) -> Int{
return p2 + 20
}
return func1(p1: x) + func2(p2: y)
}
print("嵌套函數(shù)返回值:\(moreFun(x: 1, y: 2))")
//result:33