Swift基础入门之闭包和函数

416 阅读3分钟

闭包(closures

  • OC中的block类似

  • 优势

    • 闭包体只有一行代码,可以省略return
    • $0,$1表示第i个参数
    • 提供了尾随闭包语法(trailing closure syntax)
  • 定义和使用

    参数、返回值和in都可以省略
    let studname = {
        print("swift 闭包")
    }
    
    studname()
    
    let divide = { (val: Int, val2: Int) -> Int in
        return val * val2
    }
    
    let result = divide(200,20)
    
  • sorted

    // 原数组不会被改变,返回新数组
    var reversed = name.sorted(by: backward(s1:s2:))
    
    // 通过参数缩写来调用闭包的参数
    var reversed1 = name.sorted(by: {$0 > $1})
    
    // 运算符函数,string类型定义了关于大于号(>)的字符串实现,其作为一个函数接收两个String并返回Bool,    与sorted方法的第二个参数函数类型符合
    var reversed2 = name.sorted(by: >)
    
    // 使用尾随闭包
    let reversed3 = name.sorted(){$0 > $1}
    
  • 尾随闭包

    • 书写在函数括号之后的闭包
    func someMethod(closure: () -> Void) {
    print("someMethod")
    closure()
    }
    // 不使用尾随闭包进行函数调用
    someMethod (closure: {
        print("test")
    })
    
    // 以下是使用尾随闭包进行函数调用
    someMethod () {
        print("test1")
    }
    
    // 如果函数只需要闭包表达式一个参数,当使用闭包时,可以把()省略掉
    someMethod {
        print("test1")
    }
    
    
  • 捕获值

    func someMethod(amount : Int) -> ()->Int {
        var runningToatal = 0
        func incrementor() -> Int {
            //runningToatal 的原来的作用域已经不存在,闭包仍然可以再闭包函数体内引用和修改这些值,会存储捕获的值的副本
            runningToatal += amount
            return runningToatal
        }
        return incrementor
    }
    
    let temp = someMethod(amount: 10)
    temp()   // 输出10
    temp()   // 输出20
    

    无论您将函数/闭包赋值给一个常量还是变量,您实际上都是将常量/变量的值设置为对应函数/闭包的引用。 上面的例子中,incrementByTen指向闭包的引用是一个常量,而并非闭包内容本身。

  • 闭包是引用类型

    • 函数也是引用类型
      func someMethod(amount : Int) -> ()->Int {
      var runningToatal = 0
      func incrementor() -> Int {
          //runningToatal 的原来的作用域已经不存在,闭包仍然可以再闭包函数体内引用和修改这些值,会存储捕获的值的副本
          runningToatal += amount
          return runningToatal
      }
      return incrementor
      }
      
      let temp = someMethod(amount: 10)
      temp()   // 输出10
      temp()   // 输出20
      

函数

  • 一般函数
    func someMethod() -> Int {
        return 0
    }
    someMethod()
    
  • 返回元组的函数
    func someMethod(array: [Int]) -> (min: Int, max: Int) {
        var currentMin = array[0]
        var currentMax = array[1]
        for value in array {
            if value < currentMin {
                currentMin = value
            } else if value > currentMax {
                currentMax = value
            }
        }
        return (currentMin, currentMax)
    
    
  • 局部参数和外部函数-如果提供了外部参数名,函数调用时,则必须使用外部参数名
    func powTest (firstArg a: Int, second b: Int) -> Int {
        var res = a
        for _ in 1...b {
            res = res * a
        }
        return res
    }
    
    powTest(firstArg: 1, second: 2)
    
  • 可变参数
    可以接受0个或者多个参数,可变参数通过在类型名称后面增加(...) 来定义
    func vari<N>(menmbers: N...) {
        for i in menmbers {
            print(i)
        }
    }
    
  • I/O参数
    在参数定义前加inout 关键字,就可以改变这个参数的值
    func swapTwoInts(a: inout Int, b: inout Int) {
        let temp = a
        a = b
        b = temp
    }
    var x = 1
    var y = 2
    
    swapTwoInts(a: &x, b: &y)
    
  • 函数的类型---由函数的参数类型和返回值类型组成
    func sum(a: Int, b: Int) -> Int {
        return a + b
    }
    
    // 定义一个叫addition变量,参数和返回值都是Int,并让这个新变量指向sum函数
    var addition: (Int,Int) -> Int = sum
    
    // 函数类型作为参数类型、作为返回值类型
    func another(addition: (Int, Int) -> Int, a: Int, b: Int) ->Int {
        addition(a,b)
    }
    
    another(addition: sum, a: 12, b: 8)
    
  • 函数嵌套
    函数内定义一个新的函数,外部可以调用函数内定义的函数
    func calcDecrement(forDecrement total: Int)-> () -> Int {
        var overallDecrement = 0
        func decrementer() -> Int {
            overallDecrement -= total
            return overallDecrement
        }
        return decrementer
    }
    
    let  decrem = calcDecrement(forDecrement: 30)
    print(decrem())