1 函数结构
func <#name#>(<#parameters#>) -> <#return type#> {
<#function body#>
}
name:函数名
parameters:入参
return type:返回值
function body:函数体
-
形参只能是let,也必须是let
-
返回值可以是元祖,实现多返回值
func calculate(a:Int , b:Int ) -> (sum:Int, diff:Int) {
let sum = a + b;
return (sum, a - b)
}
let result = calculate(a: 20, b: 10);
let cS = result.sum
let cD = result.diff
- 参数标签
func goToWork(at time:String) {
print("this time is \(time)")
}
goToWork(at: "08:00")
func sum(_ a:Int ,_ b:Int ) -> Int {
return a+b
}
let b = sum(20, 10);
-
默认参数值
在省略标签时。需要特别注意,避免出错
func check(name: String = "nobody", age: Int ,job: String = "none") {
print("name:\(name) age:\(age) job:\(job)")
}
check(name: "Jack", age: 18, job: "Student")
check(name: "Jack", age: 19 )
check(age: 20)
/*
name:Jack age:18 job:Student
name:Jack age:19 job:none
name:nobody age:20 job:none
*/
-
可变参数
- 一个函数最多只能有一个可变参数
- 紧跟在可变参数后面的参数不能省略参数标签
func sum3(numbers:Int... , name:String , _ age:Int) -> String {
var total = 0
for num in numbers {
total += num
}
return "total:\(total) name:\(name) age:\(age) "
}
let res = sum3(numbers: 1,2,3,4 , name:"jav",19)
print(res)
-
输入输出参数
- 可以用 inout 定义一个输入输出参数:可以在函数内部修改外部实参的值
- 可变参数不能标记位inout
- inout参数不能有默认值
- inout参数的本质是地址传递(引用传递)
- inout参数只能传入可以被多次赋值的 :例如values[0]
var value = 10
var values = [10, 20, 30]
func change(value: inout Int) -> Int {
value = 88
return value
}
change(&value)
change(&values[0])
2 函数重载
规则:
- 函数名相同
- 函数个数不同
||
函数类型不同||
参数标签不同 - 返回值类型与函数重载无关
- 默认参数值和函数重载一起使用时会产生歧义。但编译器不会报错
- 可变参数、省略标签符、函数重载一起使用时,编译器可能会报错
//默认参数值和函数重载一起使用时会产生歧义
func sum(a:Int , b:Int ) -> Int {
return a+b
}
func sum(a:Int , b:Int ,c:Int = 10) -> Int {
return a+b+c
}
let rest = sum(a: 10, b: 20)
print("rest = \(rest)") // rest = 30 会调用第一个
3 内联函数
- 如果开启了编译器优化(Release模式下默认会开启优化),编译器会自动将函数变成内联函数
- 内联函数的作用:将函数调用展开成函数体
哪些函数不会被内联:
1. 函数体比较长的
2. 递归调用
3. 包含动态派发(动态绑定)
4. 等等...
//永远不会被内联(即使开启了编译器优化)
@inline(never) func test(){
print("test")
}
//开启了编译器优化后,即使代码很长,也会被内联(递归调用函数、动态派发函数除外)
@inline(__always) func test1(){
print("test")
}
4 函数类型
- 每一个函数都是有类型的,函数类型由
形式入参类型
、返回值类型
组成,函数类型也是类型,可以定义变量,入参或返回值
func test() {} //函数类型为:() -> void or () ->()
func sum(a:Int , b:Int ) -> Int { //函数类型为 (Int, Int) ->Int
return a+b
}
// 定义变量fn 为 函数类型,则符合该类型的函数就可以对其赋值,另外调用时不需要参数标签
var fn : (Int , Int) -> Int = sum
fn(10, 20)//调用sum时,需sum(a:10, b:20),但是这里可以省略参数标签
- 函数类型也可以作为函数参数
func sum(a:Int , b:Int ) -> Int {
return a+b
}
func diff(a:Int , b:Int ) -> Int {
return a-b
}
func funcResult(funTest:(Int, Int) -> Int, a:Int, b:Int) -> Int{
return funTest(20, 10)
}
print(funcResult(funTest: sum, a: 20, b: 10))//20
print(funcResult(funTest: diff, a: 20, b: 10))//10
-
函数类型作为函数返回值
返回值是函数类型的函数,叫做高阶函数
func next(_ input:Int) -> Int {
return input + 1
}
func previous(_ input:Int) -> Int {
return input - 1
}
func forward(_ forward:Bool ) -> (Int) -> Int {
return forward ? next : previous
}
print(forward(true)(10))//11
print(forward(false)(10))//9
4 嵌套函数
-
将函数定义在函数内部
将某些函数定义在另一个函数内部,以防止外部调用
func forward(_ forward:Bool ) -> (Int) -> Int {
func next(_ input:Int) -> Int {
return input + 1
}
func previous(_ input:Int) -> Int {
return input - 1
}
return forward ? next : previous
}
print(forward(true)(10))
print(forward(false)(10))
网友评论