zoukankan      html  css  js  c++  java
  • 一.高阶函数

    一.函数式编程中函数的特点

    1. 可以创建匿名函数
      def声明带名函数,val声明匿名函数

      scala> def triple(x:Int):Int = {3*x}
      scala> triple(2)
      res1: Int = 6
      
      scala> val triple = (x:Int) => 3*x
      scala> triple(2)
      res0: Int = 6
      
    2. 函数和数字一样,可以作为参数被传递和操作

      scala> val fun = scala.math.ceil _   // _ 把函数转变为变量
      scala> Array(1.1,2.2,3.3).map(fun)
      res2: Array[Double] = Array(2.0, 3.0, 4.0)
      
    3. 声明以函数为参数的函数
      以函数为参数时,要给出函数名,参数类型,返回值类型,作为算法的约束条件。eg:f:(Double)=>Double
      以函数为参数的函数,他的函数体要用声明前面的函数名。eg:f(0.25)

      scala> def valeOnQuarter(f:(Double)=>Double) = f(0.25)
      valeOnQuarter: (f: Double => Double)Double
      
      scala> valeOnQuarter(scala.math.ceil _)
      res4: Double = 1.0
      

    匿名函数作为参数传递给另一个函数作为算法时,该匿名函数会自行做参数类型推断,自动识别算法的参数和返回值类型,可以不去声明
    scala // 匿名函数作为算法的完整写法 scala> valeOnQuarter((x:Double)=>3*x) res5: Double = 0.75 // 参数值推断的写法 scala> valeOnQuarter(x=>3*x) res6: Double = 0.75 // 终极简化写法 scala> valeOnQuarter(3*_) res7: Double = 0.75
    【注】:匿名函数作为参数值时,之所以可以做参数类型推断,是因为以算法为参数的函数的函数体给出了参数值。如果把一个val变量声明为匿名函数,则要给出参数类型,以便scala推断返回值类型
    ```scala
    scala> val fun = 3*( _: Double)
    fun: Double => Double =

    scala> fun(2)
    res8: Double = 6.0
    ```
    

    二.集合类中有用的高阶函数(算法为参数)

    1. map与foreach

      scala> (1 to 4).map("*" * _).foreach(println)
      *
      **
      ***
      ****
      
    2. filter

      scala> (1 to 9).filter(_% 2==0)
      res14: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8)
      
    3. reduceLeft

      scala> (1 to 4).reduceLeft(_*_)
      res16: Int = 24
      
    4. sortWith

      scala> "i have a dream".split(" ").sortWith(_.length < _.length)
      res21: Array[String] = Array(i, a, have, dream)
      

    三.闭包

    1. 闭包:
      一个函数的函数体内,所用到的变量没有全部在函数内部定义。函数内部定义的变量称为绑定变量,函数未定义的称为自由变量。此时含有未定义变量的函数文本处于“开放”状态,当自由变量根据函数上文动态推断而来后,函数文本“关闭”,次过程称为函数的闭包。
      即:函数从变量个数 > 参数列表个数到变量个数 = 参数列表个数的过程,称为闭包

      scala> val more=1
      scala> def add(x:Int)={x+more}    // 函数内部没有给出more的定义,而是根据上文的more=1推断而来
      scala> add(1)
      res0: Int = 2
      
    2. 闭包的高级形式:匿名函数中包含第二个绑定变量

      scala> def add(more:Int)={(x:Int)=>x+more}     // add函数内部有2个参数,却只有一个参数列表
      
      scala> val add1=add(1)    // 此时add1的变量个数和参数列表个数相同
      add1: Int => Int = <function1>
      
      scala> add1(2)
      res2: Int = 3
      

    四.柯里化

    1. 柯里化:
      柯里化是一种函数的书写格式,他把多参函数,转化为拥有一个参数的函数
      柯里化将单个参数单拎出来,以构建用于类型推断的函数
      eg:闭包中的def add(more:Int)={(x:Int)=>x+more},add函数实际上有2个参数,more和x
      scala> def add(x:Int,y:Int)=x+y    // 2参函数的一般形式
      
      scala> def add(x:Int)=(y:Int)=>x+y    // 柯里化后的1参函数
      add: (x: Int)Int => Int
      
      scala> add(1)   // 类型推断后,add(1)=(y:Int)=>1+y
      res5: Int => Int = <function1>
      
      scala> add(1)(2)
      res6: Int = 3
      

    柯里化简写形式
    ```scala
    scala> def add(x:Int)(y:Int)=x+y
    add: (x: Int)(y: Int)Int

    scala> add(1)(2)    //add(1)(2)的调用,先转化为add(1)函数,再给这个函数传参2
    res7: Int = 3
    ```
    

    五.控制抽象

    1. scala有一个函数级别的模板设计模式,为一个算法起一个别名,声明返回值类型,在函数体内,用这些别名形成操作模板。调用这种模板函数时,可以将一系列语句组成用大括号扩起来形成函数语句块,把语句块作为参数传进这个模板函数
      eg:用控制抽象实现while..until的语法:
      scala> def until(condition: =>Boolean)(fun: =>Unit){
           |   if(!condition){
           |     fun
           |     until(condition)(fun)
           |   }
           | }
      until: (condition: => Boolean)(fun: => Unit)Unit
      
      scala> a=5
      scala> until{a==1}{a-=1
           | println(a)
           | }
      4
      3
      2
      1
      
      
  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1036. Boys vs Girls (25)
    1035 Password (20)
    1027 Colors in Mars (20)
    1009. Product of Polynomials (25)
    1006. Sign In and Sign Out
    1005 Spell It Right (20)
    1046 Shortest Distance (20)
    ViewPager页面滑动,滑动到最后一页,再往后滑动则执行一个事件
    IIS7.0上传文件限制的解决方法
  • 原文地址:https://www.cnblogs.com/72808ljup/p/5376519.html
Copyright © 2011-2022 走看看