函数是一组特定的代码块,执行特定的任务。当你需要执行一个函数体时,你只需要调用函数的标示名。
在Swift中,函数是足够强大和灵活的。你可以传递参数,并且在函数执行完毕时也可以返回数据。参数可以提供默认值,以简化函数的调用。
每一个函数都是一个类型,这意味着可以你可以将函数作为参数传递到其他函数内,并返回一个函数。也可以将其他函数封装到一个函数内形成嵌套函数。
## 定义和调用函数
下面代码定义了一个sayHello的函数,这个函数接受一个String类型的参数,并返回一个String类型的数据。当你想调用这个函数时,只需调用函数名,并传递想要传递的数据。
~~~
func sayHello(personName: String) -> String {
let greeting = "Hello, " + personName + "!"
return greeting
}
print(sayHello("阳君"))
// prints "Hello, 阳君!"
~~~
## 函数的参数和返回值
在Swift中,函数的参数和返回值是非常灵活的,你可以定义任何类型的参数和返回值。
### 函数不携带参数
~~~
// 无参数,只有一个String类型的返回值
func sayHelloWorld() -> String {
return "hello, world"
}
print(sayHelloWorld())
// prints "hello, world"
~~~
### 函数携带多个参数
~~~
// 传入两个参数,并返回一个String类型的数据
func sayHello(personName: String, alreadyGreeted: Bool) -> String {
if alreadyGreeted {
return "Hello again, \(personName)!"
} else {
return "Hello, \(personName)!"
}
}
print(sayHello("阳君", alreadyGreeted: true))
// prints "Hello again, 阳君!"
~~~
### 函数没有返回值
~~~
// 传入一个String类型的数据,不返回任何数据
func sayGoodbye(personName: String) {
print("Goodbye, \(personName)!")
}
sayGoodbye("阳君") // prints "Goodbye, 阳君!"
~~~
### 函数有返回值
### 函数有一个返回值
~~~
// 返回一个Int类型的数据
func printAndCount(stringToPrint: String) -> Int {
print(stringToPrint)
return stringToPrint.characters.count
}
printAndCount("hello, world") // prints "hello, world"
~~~
### 函数有多个返回值
~~~
// 返回元组数据
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"
~~~
### 返回类型可选
当函数执行完毕时,会返回一定的数据。在有的情况下函数会返回nil的数据,此时只需要在声明的函数返回类型后添加“?”。
~~~
// 返回一个元组或Nil
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([8, -6, 2, 109, 3, 71]) {
print("min is \(bounds.min) and max is \(bounds.max)")
// prints "min is -6 and max is 109"
}
~~~
## 参数名
### 指定外部参数名
在外部调用函数时,我们希望在传递参数的数据前有提示,这样提升了代码的阅读性。如`sayHello("Bill", "Ted")` 增加外部参数名后变为`sayHello(to: "Bill", and: "Ted")`。
~~~
// 指定外部参数名to和and
func sayHello(to person: String, and anotherPerson: String) -> String {
return "Hello \(person) and \(anotherPerson)!"
}
print(sayHello(to: "Bill", and: "Ted"))
// prints "Hello Bill and Ted!"
~~~
### 省略外部参数名
在一些特有的情况下,我们并不需要外部参数名。由于swift的函数机制,除第一个外的其他参数必须携带外部参数名。如果你不想使用外部参数名,在声明的时候可使用`_` 代替参数名。
~~~
// 使用_省略外面参数名,
func someFunction(firstParameterName: Int, _ secondParameterName: Int) {
}
someFunction(1, 2)
~~~
### 参数默认值
在函数内部,我们可以为参数设置默认值。如果外部不传递数据时,我们就使用设置的默认值。
~~~
// 设置默认值,当用户不传入时,使用默认值
func someFunction(parameterWithDefault: Int = 12) {
print("\(parameterWithDefault)")
}
someFunction(6) // 6
someFunction() // 12
~~~
### 可变参数
有的时候,我们只知道传入函数的数据类型,不知道传入函数的数据个数,这个时候我们可以使用`...`代表允许传入未知个数的数据。
~~~
// 传入的参数类型已知Double,个数未知
func arithmeticMean(numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
print("\(arithmeticMean(1, 2, 3, 4, 5))") // 3.0
print("\(arithmeticMean(3, 8.25, 18.75))") // 10.0
~~~
### 常量和变量参数
在函数中,参数默认是let不可变。如果我们想让这个数据可变,可能需要在函数内用一个var转化。Swift鉴于这种情况,对参数做了优化,我们只需要用var声明这个参数,在函数内就可改变它的数据。
~~~
// 默认为let常量参数,也可声明var可变参数,在函数内直接修改
func alignRight(var string: String, totalLength: Int, pad: Character) -> String {
let amountToPad = totalLength - string.characters.count
if amountToPad < 1 {
return string
}
let padString = String(pad)
for _ in 1...amountToPad {
string = padString + string
}
return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, totalLength: 10, pad: "-")
print("originalString:\(originalString); paddedString:\(paddedString);")
// originalString:hello; paddedString:-----hello;
~~~
### In-Out参数
当我们使用var让参数可变的时候,往往会思考我们改变这个参数的数据,是否会改变外部的数据呢?当你改变var声明的数据时,外面数据是不会发生任何改变的。但是有的情况,我们又希望外部数据也会跟着变化,此时我们只需要使用inout声明这个参数。
~~~
// 使用inout声明的参数,在函数内修改参数值时,外面参数值也会变
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"
~~~
## 函数类型
所有的函数都是一个类型,只是这个类型有点特殊,它携带参数和返回值。也就意味着,你可以将一个函数用一个let或var声明的属性代替。当我们调用这个函数时,只需要调用这个声明的属性。
### 使用函数类型
~~~
// 加法
func addTwoInts(a: Int, _ b: Int) -> Int {
return a + b
}
// 乘法
func multiplyTwoInts(a: Int, _ b: Int) -> Int {
return a * b
}
// 函数体赋值为参数
var mathFunction: (Int, Int) -> Int = addTwoInts
print("Result: \(mathFunction(2, 3))") // prints "Result: 5"
// 函数体指向替换
mathFunction = multiplyTwoInts
print("Result: \(mathFunction(2, 3))") // prints "Result: 6"
// 函数体传递
let anotherMathFunction = addTwoInts //
// anotherMathFunction is inferred to be of type (Int, Int) -> Int
print("\(anotherMathFunction)")
~~~
### 函数做参数
下面的例子介绍了怎么将一个函数作为一个参数传递到另一个函数内
~~~
// 加法
func addTwoInts(a: Int, _ b: Int) -> Int {
return a + b
}
// 其中一个参数为一个函数体
func printMathResult(mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5) // prints "Result: 8"
~~~
### 函数做返回值
函数作为函数的参数传递,也就意味着函数可以作为函数的返回值。
~~~
// 加1
func stepForward(input: Int) -> Int {
return input + 1
}
// 减1
func stepBackward(input: Int) -> Int {
return input - 1
}
// 使用函数体做返回类型
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
return backwards ? stepBackward : stepForward
}
var currentValue = 3
// 此时moveNearerToZero指向stepForward函数
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// 调用函数体
currentValue = moveNearerToZero(currentValue)
print("\(currentValue)... ") // prints “2...”
~~~
## 嵌套函数
本章介绍的函数体都是全局函数的例子,它被定义在全局作用域中。您也可以在一个函数体内再定义一个函数,称为嵌套函数。
嵌套函数默认情况下是隐藏的,但你仍然可以调用和使用嵌套函数外的数据。
~~~
// 函数体内部嵌套函数,并做返回类型
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
// 嵌套函数1
func stepForward(input: Int) -> Int {
return input + 1
}
// 嵌套函数2
func stepBackward(input: Int) -> Int {
return input - 1
}
return backwards ? stepBackward : stepForward
}
var currentValue = -2
let moveNearerToZero = chooseStepFunction(currentValue > 0)
currentValue = moveNearerToZero(currentValue)
print("\(currentValue)... ") // prints "-1..."
~~~
## 其他
### 参考资料
[The Swift Programming Language (Swift 2.1)](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html)
### 文档修改记录
| 时间 | 描述 |
|-----|-----|
| 2015-10-27 | 根据 [The Swift Programming Language (Swift 2.1)](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html)总结 |
版权所有:[http://blog.csdn.net/y550918116j](http://blog.csdn.net/y550918116j)
- 前言
- Swift函数
- Swift闭包(Closures)
- Swift枚举(Enumerations)
- Swift类和结构体(Classes and Structures)
- Swift属性(Properties)
- Swift方法(Methods)
- Swift下标(Subscripts)
- Swift继承(Inheritance)
- Swift初始化(Initialization)
- Swift销毁(Deinitialization)
- Swift可选链(Optional Chaining)
- Swift错误处理(Error Handling)
- Swift类型选择(Type Casting)
- Swift协议(Protocols)
- Swift访问控制(Access Control)
- Swift高级运算符(Advanced Operators)