美文网首页
函数类型与闭包

函数类型与闭包

作者: 霏誠拜咬o | 来源:发表于2016-07-08 17:36 被阅读0次

    函数类型

    • 函数类型定义:(参数类型1,参数类型2,……)->返回值类型
    • 函数类型是一种引用类型,类似于函数指针。可以将函数类型应用于任何使用类型的地方:变量、参数、返回值。
    • 函数类型实例化支持:
      • 全局函数
      • 嵌套函数
      • 成员函数(实例方法 与 静态方法)
    func add(x:Double, y:Double)->Double{
      return x+y
    }
    
    func minus(x:Double, y:Double)->Double{
      return x-y
    }
    
    func mulitiply(x:Double, y:Double)->Double{
      return x*y
    }
    
    func divide(x:Double,y:Double)->Double{
      return x/y
    }
    
    class Matrix{
      var row=0.0
      var column=0.0
    
      init(row:Double ,colomn:Double){
        self.row=row
        self.column=column
    }
    
      func process(x:Double, y:Double)->Double{
        return x*row+y*column
    }
      
      static func invoke(x:Double, y:Double)->Double{
        return x*y+y*y
    }
    }
    //函数类型作为变量
    var compute:(Double, Double)->Double
    
    compute=add //全局函数
    let result1=compute(100,200)
    
    compute=divide
    let result2=compute(300,40)
    
    var matrix=Matrix(row:10.0,column:20.0)
    compute=matrix.process //实例方法
    //compute.object=matrix
    //compute.method=&process
    compute(80,60)//JMP  compute.method
    
    compute=Matrix.invoke //静态方法
    compute(30,40)
    
    //函数类型作为参数
    func process(math: (Double,Double)->Double,x:double,y:Double){
      let result=math(x,y)
      print("result:\(result)")  
    }
    
    process(multiply,x:30,y:50)
    
    //函数类型作为返回值
    func calculateFunction(symbol:String)->(Double,Double)->Double{
      switch(symbol){
      case "+":
               return add
      case "-":
               return minus
      case "*":
               return multiply
      case "/":
               return divide
      default:
          return add
      }
    }
    
    var calculate=calculateFunction("-")
    let result3 = calculate(300,80)
    
    //嵌套函数
    func algorithmFunction(symbol:String)-> (Double, Double)->Double{
      func add(x:Double, y:Double)->Double{
        return x+y
      }
    
      func minus(x:Double, y:Double)->Double{
        return x-y
      }
    
      func mulitiply(x:Double, y:Double)->Double{
        return x*y
      }
    
      func divide(x:Double,y:Double)->Double{
        return x/y
      }
      switch(symbol){
        case "+":
               return add
        case "-":
               return minus
        case "*":
               return multiply
        case "/":
               return divide
        default:
          return add
      }
    }
    
    var algorithm=algorithmFuntion("/")
    let result4 = algorithm(600,80)
    
    函数类型的内存模型.png

    compute=全局函数时,对象指针为空
    认识闭包Closure
    =====================

    • 闭包是函数类型的实例,一段自包含的代码块,可被用于函数类型的变量,参数或返回值。

    • 三种闭包形式:

      • 全局函数:具名函数,但不捕获任何值
      • 嵌套函数:在函数内部嵌套定义具名函数,可捕获包含函数中的值
      • 闭包表达式:匿名函数类型实例,不具名的代码块,可捕获上下文中的值
    • 闭包是引用类型,闭包变量拷贝具有引用语义。

    • 闭包和函数类型实例拥有同样的内存模型。

    class Rectangle {
      var width=0
      var length=0
    
      init(width:Int, length:Int){
        self.width=width
        self.length=length
      }
    }
    
    func <= (left: Rectangle, right: Rectangle) -> Bool {
      return left.width*left.length<=right.width*right.length
    }
    
    func compare(first:Rectangle, second: Rectangle)->Bool{
      return first.width*first.length<=second.width*second.length
    }
    
    var rects = [Rectangle(width:6,length:7),
                 Rectangle(width:5,length:8),
                 Rectangle(width:9,length:6)]
    
    //函数类型对象
    /*
    func sort(@noescape isOrderedBefore: (Self.Generator.Element,Self.Generator.Element) -> Bool) -> [Self.Generator.Element]
    */
    //func sort(isOrderedBefore:(Rectangle,Rectangle)->Bool)->[Rectangle]
    
    var predict:  (Rectangle,Rectangle)->Bool
    predict=compare
    rects.sort(predict)
    
    rects.sort(compare) //不用上面那样绕
    
    
    //闭包表达式
    rects.sort({(first:Rectangle, second:Rectangle)->Bool in
    
      return first.width*first.length<=second.width*second.length
    })
    
    
    let expression={(first:Rectangle, second:Rectangle)->Bool in
      return first.width*first.length<=second.width*second.length
    }
    rects.sort(exprssion)//也可以这么写
    
    //自动类型推断
    rects.sort({first,second in
      return first.width*first.length<=second.width*second.length
    })
    
    //单表达式省略return
    rects.sort({first,second in first.width*first.length<=second.width*second.length})
    
    //参数缩略形式
    rects.sort({$0.width*$0.length<=$1.width*$1.length})
    
    //操作符缩略式
    rects.sort( <= ) //rects.sort(compare)
    
    //尾随闭包
    rects.sort{
      first,second in
      first.width*first.length<=second.width*second.length
    }
    
    rects.sort{$0.width*$0.length<=$1.width*$1.length}
    
    //自动闭包
    var cities = ["Beijing","shanghai","New York","Paris","London"]
    print(cities.count)
    
    let filter = {cities.removeLast()}//()->String
    print(cities.count)
    
    print("Deleting\(filter())!")
    print(cities.count)
    

    闭包表达式

    {(参数1,参数2……)->返回值类型 in
    语句块
    }

    • 几种简化缩写形式:
      • 自动类型推断:省略参数类型和返回值类型
      • 单表达式闭包可以省去return关键词。
      • 使用参数缩略形式$0,$1...省略参数声明和in
      • 将操作符函数自动推导为函数类型
      • 尾随闭包:当闭包表达式为函数最后一个参数,可将其写在括号后
      • 自动闭包:不接受任何参数,直接返回表达式的值。允许延迟计算

    函数类型与闭包的变量捕获

    • 函数类型和闭包可以捕获其所在上下文的任何值:

      • 函数参数
      • 局部变量
      • 对象实例属性
      • 全局变量
      • 类的类型属性
    • 如果捕获值生存周期小于闭包对象(参数和局部变量),系统会将被捕获的值封装在一个临时对象里,然后在闭包对象上创建一个对象指针,指向该临时对象。

    • 临时对象和闭包对象之间是强引用关系,生存周期跟随闭包对象。

    var data=100
    
    //捕获实例属性
    class Rectangle{
      var width=0
      var length=0
    
      static var max=100
    
      init(width:Int,length:Int){
        self.width=width
        self.length=length
      }
    
      func getComputeHandler()->() -> Int{
        return {
          return self.width*self.length
        }
      }
    }
    var rect=Rectangle(width:10,length:20)
    var handler=rect.getComputeHandler()
    handler()
    
    //捕获参数或局部变量
    func addHandler(var step: Int) -> () -> Int {
      var sum = 0
      return {
        sum += step
        data++
        Rectangle.max++
        step++
        return sum
      }
    /*  func add() ->Int {
        sum+=step
    
        return sum  
      }
      return add*/
      
    }
    let addByTen=addHandler(10)
    
    addByTen()
    addByTen()
    addByTen()
    print(data)
    print(Rectangle.max)
    
    let addBYSix=addHandler(6)
    
    addBySix()
    addBySix()
    addBySix()
    print(data)
    print(Rectangle.max)
    
    /*class AddHelper {
      var sum=0
      var step=0
    
      func add() -> Int {
        self.sum+=self.step
        return self.sum
      }
    }
    
    func addHandlerHelper(step: Int) -> () -> Int {
      let sum=0
      let obj=AddHelper()
      obj.sum=sum
      obj.step=step
      let closuer=obj.add
      return closuer
    }
    
    let addByTen=addHandlerHelper(10)
    
    print(addByTen())
    print(addByTen())
    print(addByTen())
    
    let addByTen=addHandlerHelper(6)
    
    print(addBySix())
    print(addBySix())
    print(addBySix())*/
    
    捕获值的内存模型.png

    相关文章

      网友评论

          本文标题:函数类型与闭包

          本文链接:https://www.haomeiwen.com/subject/elafjttx.html