函數是一組用於執行特定任務的獨立的代碼段,你用一個名字來標識函數,這個名字是用來“調用”函數來執行它的任務。 swift統一函數的語法具有足夠的靈活性來表達任何一個簡單的不帶參數的名稱與本地和外部的每個參數的參數名稱的複雜objective-c-style C風格的函數方法。參數可以提供預設值,以簡 ...
函數是一組用於執行特定任務的獨立的代碼段,你用一個名字來標識函數,這個名字是用來“調用”函數來執行它的任務。
swift統一函數的語法具有足夠的靈活性來表達任何一個簡單的不帶參數的名稱與本地和外部的每個參數的參數名稱的複雜objective-c-style C風格的函數方法。參數可以提供預設值,以簡化函數調用,並且可以通過在輸出參數中,一旦該功能完成了它的執行,它就可以修改傳遞的變數
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類型的數據,使用->符號來標識函數的返回類型,後面是函數的返回類型。
函數的形參和返回值
函數參數和返回值是非常靈活的。您可以從一個簡單的實用程式函數中定義任何一個簡單的函數,用一個未命名的參數來定義一個複雜的函數。
無參函數
func sayHelloWorld() -> String {
return "hello, world"
}
print(sayHelloWorld())
// Prints "hello, world
多參函數
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!