博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一.高阶函数
阅读量:4309 次
发布时间:2019-06-06

本文共 2854 字,大约阅读时间需要 9 分钟。

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

  1. 可以创建匿名函数

    def声明带名函数,val声明匿名函数
    scala scala> def triple(x:Int):Int = {3*x} scala> triple(2) res1: Int = 6
    scala scala> val triple = (x:Int) => 3*x scala> triple(2) res0: Int = 6

  2. 函数和数字一样,可以作为参数被传递和操作

    scala 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
    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)=>3x)
    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 scala> val more=1 scala> def add(x:Int)={x+more} // 函数内部没有给出more的定义,而是根据上文的more=1推断而来 scala> add(1) res0: Int = 2

  2. 闭包的高级形式:匿名函数中包含第二个绑定变量

    ```scala
    scala> def add(more:Int)={(x:Int)=>x+more} // add函数内部有2个参数,却只有一个参数列表

    scala> val add1=add(1) // 此时add1的变量个数和参数列表个数相同

    add1: Int => Int =

    scala> add1(2)

    res2: Int = 3
    ```

四.柯里化

  1. 柯里化:

    柯里化是一种函数的书写格式,他把多参函数,转化为拥有一个参数的函数
    柯里化将单个参数单拎出来,以构建用于类型推断的函数
    eg:闭包中的def add(more:Int)={(x:Int)=>x+more},add函数实际上有2个参数,more和x
    ```scala
    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 =

    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
    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

    ```

转载于:https://www.cnblogs.com/72808ljup/p/5376519.html

你可能感兴趣的文章
Java中Synchronized的用法
查看>>
阻塞队列
查看>>
linux的基础知识
查看>>
接口技术原理
查看>>
五大串口的基本原理
查看>>
PCB设计技巧与注意事项
查看>>
linux进程之间通讯常用信号
查看>>
main函数带参数
查看>>
PCB布线技巧
查看>>
关于PCB设计中过孔能否打在焊盘上的两种观点
查看>>
PCB反推理念
查看>>
京东技术架构(一)构建亿级前端读服务
查看>>
php 解决json_encode中文UNICODE转码问题
查看>>
LNMP 安装 thinkcmf提示404not found
查看>>
PHP empty、isset、innull的区别
查看>>
apache+nginx 实现动静分离
查看>>
通过Navicat远程连接MySQL配置
查看>>
phpstorm开发工具的设置用法
查看>>
Linux 系统挂载数据盘
查看>>
Git基础(三)--常见错误及解决方案
查看>>