函數是一組用於執行特定任務的獨立的代碼段,你用一個名字來標識函數,這個名字是用來「調用」函數來執行它的任務。objective-c
swift統一函數的語法具備足夠的靈活性來表達任何一個簡單的不帶參數的名稱與本地和外部的每一個參數的參數名稱的複雜objective-c-style C風格的函數方法。參數能夠提供默認值,以簡化函數調用,而且能夠經過在輸出參數中,一旦該功能完成了它的執行,它就能夠修改傳遞的變量swift
swift每個函數都有一個類型,由形參類型和返回類型組成。你能夠使用這種類型的任何其餘類型,這使得它很容易將函數做爲參數的其餘函數,並返回函數的函數。函數還能夠用其餘函數來封裝在嵌套函數做用域內的有用函數。數組
定義和調用函數函數
func sayHello(personName: String) -> String { let greeting = "Hello, " + personName + "!" return greeting }
print(sayHello("Anna")) // Prints "Hello, Anna!" print(sayHello("Brian")) // Prints "Hello, Brian!
sayHello是函數的名稱,personName是它的參數,類型是String,返回一個String類型的數據,使用->符號來標識函數的返回類型,後面是函數的返回類型。spa
函數的形參和返回值code
函數參數和返回值是很是靈活的。您能夠從一個簡單的實用程序函數中定義任何一個簡單的函數,用一個未命名的參數來定義一個複雜的函數。blog
無參函數three
func sayHelloWorld() -> String { return "hello, world" } print(sayHelloWorld()) // Prints "hello, world
多參函數ip
func sayHello(personName: String, alreadyGreeted: Bool) -> String { if alreadyGreeted { return sayHelloAgain(personName) } else { return sayHello(personName) } } print(sayHello("Tim", alreadyGreeted: true)) // Prints "Hello again, Tim!
無返回值函數(實際返回void)作用域
func sayGoodbye(personName: String) { print("Goodbye, \(personName)!") } sayGoodbye("Dave") // Prints "Goodbye, Dave!
func printAndCount(stringToPrint: String) -> Int { print(stringToPrint) return stringToPrint.characters.count } func printWithoutCounting(stringToPrint: String) { printAndCount(stringToPrint) } printAndCount("hello, world") // prints "hello, world" and returns a value of 12 printWithoutCounting("hello, world") // prints "hello, world" but does not return a value
多返回值函數
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("min is \(bounds.min) and max is \(bounds.max)") // Prints "min is -6 and max is 109
函數形參名
函數的形參包括本地和外部參數名。外部參數名稱用於將參數傳遞給函數調用。函數的實現中使用了局部參數名稱
func someFunction(firstParameterName: Int, secondParameterName: Int) { // function body goes here // firstParameterName and secondParameterName refer to // the argument values for the first and second parameters } someFunction(1, secondParameterName: 2)
默認形參值
您能夠在參數類型以後給任何的參數設置一個默認值,若是您設置了默認值,那麼就能夠在調用該函數時忽略此參數。
func someFunction(parameterWithDefault: Int = 12) { // function body goes here // if no arguments are passed to the function call, // value of parameterWithDefault is 12 } someFunction(6) // parameterWithDefault is 6 someFunction() // parameterWithDefault is 12
在函數的參數列表的結尾處設置默認值
可變參數
一個可變的參數接受特定類型的零個或多個值。當函數被調用時,你使用一個可變的參數能夠傳入不一樣數量的指定類型的參數,在參數類型名稱後面插入...來實現可變參數。函數體的可變參數值被當作一個特定類型的數組來處理。例子以下
func arithmeticMean(numbers: Double...) -> Double { var total: Double = 0 for number in numbers { total += number } return total / Double(numbers.count) } arithmeticMean(1, 2, 3, 4, 5) // returns 3.0, which is the arithmetic mean of these five numbers arithmeticMean(3, 8.25, 18.75) // returns 10.0, which is the arithmetic mean of these three numbers
numbers: Double...被當作一個存放Double類型的數組,咱們能夠遍歷它的每個元素
注意:一個函數只能有一個可變參數
In-Out 形參
函數參數默認爲常量,在函數體內修改參數值會發生編譯時錯誤,這意味着你不能改變一個參數的值。若是你想要一個函數來修改某個參數的值,並但願這些改變在函數調用結束後是永久的,那麼使用 in-out參數來代替
使用inout關鍵字來定義一個in-out參數,可是參數不能爲常量,只能爲變量。當你調用時直接在參數名前加&符號來標識此參數能夠被該函數修改。
func swapTwoInts(inout a: Int, inout _ b: Int) { let temporaryA = a a = b b = temporaryA }
來看一下如何調用
var someInt = 3 var anotherInt = 107 swapTwoInts(&someInt, &anotherInt) print("someInt is now \(someInt), and anotherInt is now \(anotherInt)") // Prints "someInt is now 107, and anotherInt is now 3」
函數類型
每一個函數都有一個特定的函數類型,由形參類型和函數的返回類型組成
func addTwoInts(a: Int, _ b: Int) -> Int { return a + b } func multiplyTwoInts(a: Int, _ b: Int) -> Int { return a * b }
這個例子定義了addTwoInts,multiplyTwoInts2個函數,它們的類型都是(Int, Int) -> Int
func printHelloWorld() { print("hello, world") }
它的類型是()->Void
函數類型的使用
在swift中您能夠像任何其餘類型同樣的使用函數類型。例如,你能夠定義一個常量或變量爲一個函數類型,併爲變量指定一個對應的函數:
var mathFunction: (Int, Int) -> Int = addTwoInts
能夠解讀爲:"定義一個名爲mathFunction變量,該變量的類型爲'一個函數,它接受兩個Int值,並返回一個Int值。'設置這個新的變量來引用名爲addTwoInts函數。
該addTwoInts函數具備與mathFunction相同類型的變量,因此這個賦值能經過swift的類型檢查。
如今你能夠使用mathFunction來調用指定的函數:
print("Result: \(mathFunction(2, 3))") // Prints "Result: 5
與其餘類型同樣,當你給函數賦一個常量或者變量時,你可讓Swift去推斷函數的類型。
let anotherMathFunction = addTwoInts // anotherMathFunction is inferred to be of type (Int, Int) -> Int
做爲形參類型的函數類型
能夠使用一個函數類型,如(Int, Int)->Int做爲另外一個函數的形參類型。這使你預留了一個函數的某些方面的函數實現,讓調用者提供的函數時被調用。
func printMathResult(mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) { print("Result: \(mathFunction(a, b))") } printMathResult(addTwoInts, 3, 5) // Prints "Result: 8
做爲返回類型的函數類型
你能夠將一個函數類型做爲另外一個函數的返回類型。你能夠在返回函數的返回箭頭(->) 後當即編寫一個完整的函數類型來實現。下面的例子定義了兩個簡單的函數調用stepForward和stepBackward。stepForward函數返回一個輸入值+1的結果,而stepBackward函數返回一個輸入值-1的結果。這兩個函數都有一個相同的(Int) -> Int類型 :
func stepForward(input: Int) -> Int { return input + 1 } func stepBackward(input: Int) -> Int { return input - 1 }
func chooseStepFunction(backwards: Bool) -> (Int) -> Int { return backwards ? stepBackward : stepForward }
var currentValue = 3 let moveNearerToZero = chooseStepFunction(currentValue > 0) // moveNearerToZero now refers to the stepBackward() function
print("Counting to zero:") // Counting to zero: while currentValue != 0 { print("\(currentValue)... ") currentValue = moveNearerToZero(currentValue) } print("zero!") // 3... // 2... // 1... // zero!
嵌套函數
迄今爲止全部你在本章中遇到函數都是全局函數,在全局做用域中定義。其實你還能夠在其餘函數體中定義函數,被稱爲嵌套函數。嵌套函數默認對外界是隱藏的,但仍然能夠經過它們包裹的函數調用和使用它。enclosing function也能夠返回一個嵌套函數,以便在其餘做用域中使用嵌套函數。你能夠重寫上面的chooseStepFunction例子使用並返回嵌套函數:
func chooseStepFunction(backwards: Bool) -> (Int) -> Int { func stepForward(input: Int) -> Int { return input + 1 } func stepBackward(input: Int) -> Int { return input - 1 } return backwards ? stepBackward : stepForward } var currentValue = -4 let moveNearerToZero = chooseStepFunction(currentValue > 0) // moveNearerToZero now refers to the nested stepForward() function while currentValue != 0 { print("\(currentValue)... ") currentValue = moveNearerToZero(currentValue) } print("zero!") // -4... // -3... // -2... // -1... // zero!