《swift从入门到精通》(二):函数
2021-09-26 本文已影响0人
萧1帅
函数的定义
- 常见的定义函数的方式
1, num1和num2表示的形参的内部函数名
func sum(num1: Int, num2: Int) -> Int {
return num1+num2
}
let su = sum(num1:10, num2: 20)
2,在开发过程中往往会给形参设置一个名词, 这样不能大大提高函数的可读性, a和b就是形参的外部函数名
func sum( a num1: Int, b num2: Int) -> Int {
return num1+num2
}
let su = sum(a: 10, b: 20)
3,这种方式也是我在开发中常用的一种方式,直接在形参前面使用下划线“_”, 这样就会把函数名直接隐藏掉,有点是可使代码看起来更加简洁,方便
func sum( _ num1: Int, _ num2: Int) -> Int {
return num1+num2
}
let su = sum(10, 20)
注意:
函数中定义形参默认是let类型,所以不能直接去修改形参的值,如果需要修稿就使用inout关键字
如:
错误写法: num默认是let类型,不能直接修改参数的值,这样写会报错
func sum(num: Int) {
number += 1
}
var num3: Int = 5
sum(num: &num3)
报错:
error: block.playground:11:9: error: left side of mutating operator isn't mutable: 'num' is a 'let' constant
num += 3
~~~ ^
正确写法:使用关键字 inout 指向的是内存地址, 相当于C语言的&地址符号
func sum(num:inout Int) {
num += 1
}
var num3: Int = 5
sum(num: &num3) // 结果是6
- 默认参数
//默认参数值
func check(name: String = "nobody", age: Int, job: String = "noe"){
print("name=\(name), age=\(age), job=\(job)")
}
check(name: "Jack", age: 20, job: "Doctor")// name=Jack, age=20, job=Doctor
check(name: "jack", age: 10)
check(age: 10, job: "batom")
check(age: 15)
c++的默认参数有个限制:必须从右往左设置。由于seigt有参数标签,因此并没有此类限制,但是在省略参数标签时,需要特别注意,避免出错
//这里的middle不能省略参数标签
func test(_ first: Int = 10, middle: Int, _ last: Int = 30){
}
test(middle: 20)
- 可变参数
func sum(_ numbers: Int...) -> Int{
var sum = 0
for number in numbers {
sum += number
}
return sum
}
sum(10, 20, 30, 40) //100
- 一个函数最多只能有1个可变参数
- 紧跟在可变参数后面的参数不能省略参数标签
//参数string不能省略标签
func test(_ numbers: Int..., string: String, _ other: String){}
test(10, 20, 30, string: "jack", "aaa")
4.输入输出参数(inout)
可以用inout定义一个输入输出参数:可以在函数内部修改外部实参的值
func swapValues(_ v1: inout Int, _ v2: inout Int){
(v1, v2) = (v2, v1)
}
var a = 10
var b = 20
swapValues(&a, &b)
- 可变参数不能标记为inout
- inout参数不能有默认值
- inout参数只能传入可以被多次赋值的
- inout参数的本质是地址传递
- 函数重载
- 函数名相同
- 参数个数不同||参数类型不同||参数标签不同
func sum(v1: Int, v2: Int) -> Int {
v1 + v2
}
func sum(v1: Int, v2: Int, v3: Int) -> Int {
v1 + v2 + v3
}//参数个数不同
func sum(v1: Double, v2: Int) -> Double {
v1 + Double(v2)
}//参数类型不同
func sum(a: Int, v2: Int) -> Int {
a + v2
}//参数标签不同
注意点
- 返回值类型与函数重载无关
- 默认参数值和函数重载一起使用产生二义性时,编译器并不会报错
3.可变参数、省略参数标签、函数重载一起使用产生二义性时,编译有可能会报错
6.函数类型
每一个函数都有类型的,函数类型由形式参数类型、返回值类型组成
func test() {} // () ->Void 或 ()-> ()
func sum(a: Int, b: Int) -> Int {
a + b
} //(Int, Int) -> Int
var fn: (Int, Int) -> Int = sum
fn(2, 3)//调用时不需要参数标签
- 函数类型作为函数参数
func sum(v1: Int, v2: Int) -> Int {
v1 + v2
}
func difference(v1: Int, v2: Int) -> Int {
v1 - v2
}
func printResult(_ fn: (Int, Int) -> Int, a: Int, b: Int) {
print("Result: \(fn(a, b))")
}
printResult(sum, a: 10, b: 20)
printResult(difference, a: 10, b: 20)
- 函数类型作为函数返回值
func next(_ input: Int) -> Int {
input + 1
}
func previous(_ input: Int) -> Int {
input - 1
}
func forword(_ forword: Bool) -> (Int) -> Int {
forword ? next : previous
}
forword(true)(3)
forword(false)(4)
7.高阶函数
返回值是函数类型的函数,叫做高阶函数