swift基础——函数

2022-03-09  本文已影响0人  夜凉听风雨

函数分类

下面三种方式都可以
Void在swift里的定义就是空元组()

func say() -> Void {
    print("hello")
}

func say() -> () {
    print("hello")
}

func say() {
    print("hello")
}

func pi() -> Double {
    return 3.14
}
func say(text:String) {
    print(text)
}

函数的形参是let,也只能是let

func add(a:Int, b:Int) -> Int {
    return a + b
}

隐式返回

如果整个函数体是一个单一表达式,那么函数会隐式返回这个表达式

func add(a:Int, b:Int) -> Int {
    a + b // 可以省略return
}

let sum = add(a: 10, b: 20)
print(sum) // 打印: 30

函数的文档注释

注释及其效果.png

参数标签

可以修改参数标签,这样的目的是为了让函数调用的时候,更像是一个完整的英文句子,更好理解函数的意思。

func goToWork(at time:String) {
    print("time is \(time)")
}

goToWork(at: "8:00") // 很像 go to work at 8:00

可以使用下划线_省略参数标签,不过不建议这么使用

func add(_ a:Int, _ b:Int) -> Int {
    return a+b
}
add(10, 20) 

默认参数值

可以在声明方法的时候,为参数设置一个默认值,当方法调用时没传入该参数时,该参数值为默认值。

func check(name: String = "Jonas", age: Int, job: String = "none") {
    print("name=\(name),age=\(age),job=\(job)")
}

check(age: 15) // name=Jonas,age=15,job=none
check(name: "Bob", age: 20, job: "Doctor") // name=Bob,age=20,job=Doctor
check(name: "Mary", age: 18) // name=Mary,age=18,job=none
check(age: 30, job: "postman") // name=Jonas,age=30,job=postman

可变参数

在参数类型后面加...表示可以传入不等数量的参数,相当于是一个数组

func countNumber(numbers: Int...) {
    print(numbers) // [1,2,3,4,5]
}
countNumber(numbers: 1,2,3,4,5)

下面的例子在可变参数numbers后面的是student参数,它不能使用下划线来省略参数标签。

func countNumber(numbers: Int..., student: String, _ age: Int) {
    print(numbers) // [1,2,3,4,5]
}

countNumber(numbers: 1,2,3,4,5, student: "Bob", 15)

输入输出参数(In-Out-Parameter)

func change(num: inout Int) {
    num = 20
}

var number = 10
change(num: &number)
print(number) // 20

函数重载

重载的函数可以和原函数共存,虽然有多个名字一样的函数,但是也可以根据情况不同调用不同的函数。

函数重载示例.png 调用重载函数.png 返回值重构问题.png 默认参数值重构问题.png 可变参数省略参数标签重载.png

内联函数

编译器优化配置.png

@inline

// 永远不会内联,即使开启了编译器优化
@inline(never) func test() {
    print("hello")
}

// 开启编译器优化后,即使函数内的代码很多,也会被内联(递归调用函数,动态派发的函数除外)
@inline(__always) func test() {
    // ...很多的代码
}

release模式下,编译器开启优化,会自动决定内联函数,所以这个@inline也基本不用。

函数类型

func method() {} // 函数类型:() -> Void 或者() -> ()

func add(a: Int, b: Int) -> Int {
    return a + b
} // 函数类型:(Int, Int) -> Int
func method() {} // 函数类型:() -> Void 或者() -> ()

func add(a: Int, b: Int) -> Int {
    return a + b
} // 函数类型:(Int, Int) -> Int

var fn : (Int, Int) -> Int = add
fn(10, 20) // 30 调用时不需要参数标签
func add(a: Int, b: Int) -> Int {
    return a + b
} // 函数类型:(Int, Int) -> Int

func printResult(mathFn: (Int, Int) -> Int, a: Int, b: Int) {
    let result = mathFn(a, b)
    print(result)
}

printResult(mathFn: add, a: 20, b: 30) // 50
func add(num: Int) -> Int {
    return num + 1
}

func reduce(num: Int) -> Int {
    return num - 1
}

func select(result: Bool) -> (Int) -> Int {
    return result ? add : reduce
}

// select返回的是add函数
select(result: true)(10) // add函数传入10结果为11

typealias

typealias用来给类型起别名

// 为一个元组起别名为DateType
typealias DateType = (year: Int, month: Int, day: Int)

func method(date: DateType) {
    print("今天是\(date.year)年\(date.month)月\(date.day)日")
}
method(date: (2022, 3, 10)) // 今天是2022年3月10日
// 为一个函数类型起别名为fnType
typealias fnType = (Int, Int) -> Int

func add(a: Int, b: Int) -> Int {
    a + b
}

let method : fnType = add
method(10, 20) // 30

嵌套函数

func selectMethod(result: Bool) -> (Int, Int) -> Int {
    func add(a: Int, b: Int) -> Int {
        a + b
    }
    
    func reduce(a: Int, b: Int) -> Int {
        a - b
    }
    
    return result ? add : reduce
}

let fn = selectMethod(result: true) // add
fn(10, 20) // 30
上一篇 下一篇

猜你喜欢

热点阅读