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(site:"www.aa.com"))
函式呼叫
我們可以通過函式名以及對應型別的引數值來呼叫函式,函式的引數傳遞的順序必須與引數列表相同。
以下我們定義了一個函式名為 runoob 的函式,形參 site 的資料型別為 String,之後我們呼叫函式傳遞的實參也必須 String 型別,實參傳入函式體後,將直接返回,返回的資料型別為 String。
import Cocoa func runoob(site: String) -> String { return (site) } print(runoob(site: "www.av.com"))
函式引數
函式可以接受一個或者多個引數,這些引數被包含在函式的括號之中,以逗號分隔。
以下例項向函式 runoob 傳遞站點名 name 和站點地址 site:
import Cocoa func runoob(name: String, site: String) -> String { return name + site } print(runoob(name: "學習:", site: "www.aa.com")) print(runoob(name: "Google:", site: "www.google.com"))
不帶引數函式
我們可以建立不帶引數的函式。
func funcname() -> datatype { return datatype }
元組作為函式返回值
函式返回值型別可以是字串,整型,浮點型等。
元組與陣列類似,不同的是,元組中的元素可以是任意型別,使用的是圓括號。
你可以用元組(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(array: [8, -6, 2, 109, 3, 71]) print("最小值為 \(bounds.min) ,最大值為 \(bounds.max)")
minMax(_:)函式返回一個包含兩個Int值的元組,這些值被標記為min和max,以便查詢函式的返回值時可以通過名字訪問它們。
如果你不確定返回的元組一定不為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(array: [8, -6, 2, 109, 3, 71]) { print("最小值為 \(bounds.min),組大值為 \(bounds.max)") }
沒有返回值函式
下面是 runoob(_:) 函式的另一個版本,這個函式接收網址引數,沒有指定返回值型別,並直接輸出 String 值,而不是返回它:
import Cocoa func runoob(site: String) { print("aa:\(site)") } runoob(site: "http://www.aa.com")
函式引數名稱
函式引數都有一個外部引數名和一個區域性引數名。
區域性引數名
區域性引數名在函式的實現內部使用。
func sample(number: Int) {// number 為區域性引數名,只能在函式體內使用 println(number) }
外部引數名
你可以在區域性引數名前指定外部引數名,中間以空格分隔,外部引數名用於在函式呼叫時傳遞給函式的引數。
如下你可以定義以下兩個函式引數名並呼叫它:
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)
可變引數
可變引數可以接受零個或多個值。函式呼叫時,你可以用可變引數來指定函式引數,其數量是不確定的。
可變引數通過在變數型別名後面加入(...)的方式來定義。
import Cocoa func vari<N>(members: N...){ for i in members { print(i) } } vari(members: 4,3,5) vari(members: 4.5, 3.1, 5.6) vari(members: "Google", "Baidu", "Runoob")
常量,變數及 I/O 引數
一般預設在函式中定義的引數都是常量引數,也就是這個引數你只可以查詢使用,不能改變它的值。
如果想要宣告一個變數引數,可以在引數定義前加 inout 關鍵字,這樣就可以改變這個引數的值了。
import Cocoa func swapTwoInts(_ a: inout Int, _ b: inout Int) { let temporaryA = a a = b b = temporaryA } var x = 1 var y = 5 swapTwoInts(&x, &y) print("x 現在的值 \(x), y 現在的值 \(y)")
swapTwoInts(_:_:) 函式簡單地交換 a 與 b 的值。該函式先將 a 的值存到一個臨時常量 temporaryA 中,然後將 b 的值賦給 a,最後將 temporaryA 賦值給 b。
需要注意的是,someInt 和 anotherInt 在傳入 swapTwoInts(_:_:) 函式前,都加了 & 的字首。
函式型別及使用
每個函式都有種特定的函式型別,由函式的引數型別和返回型別組成。
func inputs(no1: Int, no2: Int) -> Int { return no1/no2 }
inputs 函式型別有兩個 Int 型的引數(no1、no2)並返回一個 Int 型的值。
import Cocoa func inputs(no1: Int, no2: Int) -> Int { return no1/no2 } print(inputs(no1: 20, no2: 10)) print(inputs(no1: 36, no2: 6))
使用函式型別
在 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))")
函式型別作為引數型別、函式型別作為返回型別
我們可以將函式作為引數傳遞給另外一個引數:
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(addition: sum, a: 10, b: 20)
函式巢狀
函式巢狀指的是函式內定義一個新的函式,外部的函式可以呼叫函式內定義的函式。
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())