---页首---

Swift从入门到精通第二篇 - 函数

函数

环境Xcode 11.0 beta4 swift 5.1

  • 函数的定义

    // func 函数名(参数列表) -> 返回值 {
    //	函数体
    // }
    // 形参默认是`let`,也只能是`let`
    // 例如
    func function(v1: Int, v2: Int) -> Int{
    	return v1 + v2
    }
    
  • 隐式返回(Implicit Return)

    // 如果整个函数体是一个单一的表达式,那么函数会隐式返回这个表达式
    func sum(v1: Int, v2: Int) -> Int {
    	v1 + v2
    }
    sum(v1: 10, v2: 20) // 30
    
  • 返回元组:实现多返回值

    func calculate(v1: Int, v2: Int) -> (sum: Int, difference: Int, average: Int){
    	let sum = v1 + v2
    	return (sum, v1 - v2, sum >> 1)
    }
    let result = calculate(v1: 20, v2: 10)
    result.sum // 30 or result.0
    result.difference // 10 or result.1
    result.average // 15 or result.2
    
  • 函数文档注释
    函数文档注释
    [Swift官方文档注释指导规范]

  • 参数标签

    // at 参数标签  time 参数名称
    func goToWork(at time: String){
    	print("this time is \(time)")
    }
    goToWork(at: "09:00")
    // 参数标签省略
    func goToWork2(_ time: String){
    	print("this time is \(time)")
    }
    goToWork2("09:00")
    func goToWork3(time: String) {
    	print("this time is \(time)")
    }
    goToWork3(time: "09:00")
    
  • 默认参数值(Default Parameter Value)

    • 参数可以有默认值,由于有参数标签可以不用像C++那样必须从右到左设置参数默认值
    func check(name: String = "nobody", age: Int, job: String = "none"){
    	print("name = \(name), age = \(age), job = \(job)")
    }
    check(name: "Jack", age: 18, job: "Actor")
    check(name: "Rose", age: 18)
    check(age: 18)
    
    • 注意:当有其它参数有默认参数时,没有设置默认参数的参数标签是不能省略的
  • 可变参数(Variadic Parameter)

    func sum(_ numbers: Int...) -> Int{
    var total = 0
    for number in numbers {
        total += number
    }
    	return total
    }
    sum(1, 2, 3, 4) // 10
    
    • 一个函数最多只能有一个可变参数
    • 紧跟在可变参数后面的参数不能省略参数标签
    // 参数string不能省略标签
    func test(_ numbers: Int..., string: String, _ other: String){ }
    
  • 输入输出参数(In-Out-Parameter)

    • 可以用inout定义一个输入输出参数:可以在函数内部修改外部实参的值
    func swapValues(_ v1: inout Int, _ v2: inout Int) {
        let tmp = v1
        v1 = v2
        v2 = tmp
    }
    func swapValues2(_ v1: inout Int, _ v2: inout Int) {
        (v1, v2) = (v2, v1)
    }
    
    • 可变参数不能标记为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: Int, v2: Double) -> Double {
    	Double(v1) + v2
    }
    func sum(v1: Double, v2: Int) -> Double {
    	v1 + Double(v2)
    }
    
    // 参数标签不同
    func sum(_ v1: Int, _ v2: Int) -> Int {
    	v1 + v2
    }
    func sum(a: Int, b: Int) -> Int {
    	a + b
    }
    
    • 重载注意点

    返回值类型与重载无关
    默认参数和函数重载同时使用时在C++中会报错,但在Swift中有时不会,如下

    func sum(v1: Int, v2: Int) -> Int {
    	v1 + v2
    }
    func sum(v1: Int, v2: Int, v3: Int = 10) -> Int {
    	v1 + v2 + v3
    }
    sum(v1: 1, v2: 2) // 会调用sum(v1: Int, v2: Int)
    

    可变参数、省略参数标签、函数重载三者同时使用产生二义性,如下

    func sum(_ numbers: Int...) -> Int{
    var total = 0
    for number in numbers {
        total += number
    }
    return total
    }
    func sum(_ v1: Int, _ v2: Int) -> Int {
         v1 + v2
    }
    func sum(v1: Int, v2: Int) -> Int {
         v1 - v2
    }
    
    • 上面任意两个同时使用在当前环境下并不会报错
  • 嵌套函数(Nested Function)

    将函数定义在函数内部

    func forward(_ forward: Bool) -> (Int) -> Int {
    	func next(_ input: Int) -> Int {
    		input + 1
    	}
    	func previous(_ input: Int) -> Int {
    		input - 1
    	}
    	return forward ? next : previous
    }
    // forward(true)(3) // 4
    // forward(false)(3) // 2
    
posted @ 2019-09-03 14:23  20190311  阅读(244)  评论(0编辑  收藏  举报
---页脚---