zoukankan      html  css  js  c++  java
  • 6.Scala-高阶函数

    第6章 高阶函数

    6.1 作为参数的函数

    函数作为一个变量传入到另一个函数中,那么该作为参数的函数的类型是:function1,即:

    (参数类型)=> 返回值

    //6.1 作为参数的函数
    def plus(x: Int) = 3 + x
    val result1 = Array(1, 2, 3, 4).map(plus(_))
    println(result1.mkString(","))

    尖叫提示:带有一个参数的函数的类型是function1,带有两个参数的是function2,以此类推。

    笔记:

    //6.1 作为参数的函数
    def match1(): Unit = {
      def plus(x: Int) = 3 + x
      val result1 = Array(1, 2, 3, 4).map(plus(_))
      println(result1.mkString(",")) //4,5,6,7
    }
    match1()

    6.2 匿名函数

    即没有名字的函数,可以通过函数表达式来设置匿名函数。

    val triple = (x: Double) => 3 * x
    println(triple(3))
    //使用方法: Array(3.14, 1.42, 2.0).map(triple) //包含在()中 Array(3.14, 1.42, 2.0).map((x: Double) => 3 * x) // 包含在{}中 Array(3.14, 1.42, 2.0) map { (x: Double) => 3 * x }

    笔记:

    //6.2 匿名函数
    def match2(): Unit = {
      val triple = (x: Double) => 3 * x
      println(triple(3)) //9.0
    
      //使用方法:
      println(Array(3.14, 1.42, 2.0).map(triple).mkString(", ")) //9.42, 4.26, 6.0
      //包含在()中
      println(Array(3.14, 1.42, 2.0).map((x: Double) => 3 * x).mkString(", "))
      // 包含在{}中
      println(Array(3.14, 1.42, 2.0) map { (x: Double) => 3 * x } mkString(", "))
    }
    match2()

    6.3 高阶函数

    能接受函数作为参数的函数,叫做 高阶函数。
    1)高阶函数的使用
    def highOrderFunction1(f: Double => Double) = f(10)
    def minus7(x: Double) = x -7
    val result2 = highOrderFunction1(minus7)
    println(result2)
     
    2)高阶函数同样可以返回函数类型
    def minusxy(x: Int) = (y: Int) => x - y
    val result3 = minusxy(3)(5)
    println(result3)
     

     

    6.4 参数(类型)推断

    // 传入函数表达式
    valueAtOneQuarter((x: Double) => 3 * x)
    // 参数推断省去类型信息
    valueAtOneQuarter((x) => 3 * x)
    // 单个参数可以省去括号
    valueAtOneQuarter(x => 3 * x)
    // 如果变量旨在=>右边只出现一次,可以用_来代替
    valueAtOneQuarter(3 * _)

    6.5 闭包

    闭包就是一个函数把外部的那些不属于自己的对象也包含(闭合)进来了。
    def minusxy(x : Int) = (y : Int) => x - y
    println(minusxy(10)(20))

     这就是一个闭包

     
    1) 匿名函数(y : Int) => x - y 嵌套在函数 minusxy 中。
    2) 匿名函数(x : Int) => x - y 使用了外部变量、mulBy 的局部变量 x。不是全局变量
    3) 函数 minusxy 返回了引用局部变量的匿名函数。 

    再举一个例子:

    def minusxy(x: Int) = (y: Int) => x - y
    val f1 = minusxy(10)
    val f2 = minusxy(10)
    println(f1(3) + f2(3))

    此处 f1,f2 这两个函数就叫闭包 。

    6.6 柯里化

    函数编程中,接受多个参数的函数都可以转化为接受单个参数的函数,
    这个转化过程就叫柯里化,柯里化就是证明了函数只需要一个参数而已。
     
    1)柯里化示例
    // 传统定义两个参数
    def mul(x:Int, y: Int) = x * y
    println(mul(6,7))
    
    // 柯里化定义,使用到了闭包
    def mulOneAtATime(x: Int) = (y: Int) => x * y
    println(mulOneAtATime(6)(7))
    
    // Scala 中可以简写
    def mulOneAtATime(x: Int)(y: Int) = x * y
    println(mulOneAtATime(10)(8))

    2)柯里化的应用

    比较两个字符串再忽略大小写的情况下是否相等,注意,这里是两个任务:

    1、全部转大写(或小写)

    2、比较是否相等

    针对这两个操作,我们用一个函数去处理的思想,其实无意间也变成了两个函数处理的思想。

    示例如下:

    val a = Array("Hello", "World")
    val b = Array("hello", "world")
    // def corresponds[B](that: GenSeq[B])(p: (A,B) => Boolean): Boolean
    println(a.corresponds(b)(_.equalsIgnoreCase(_)))
    corresponds 函数的定义使用了柯里化
    源码如下:
      def corresponds[B](that: GenSeq[B])(p: (A,B) => Boolean): Boolean = {
        val i = this.iterator
        val j = that.iterator
        while (i.hasNext && j.hasNext)
          if (!p(i.next(), j.next()))
            return false
    
        !i.hasNext && !j.hasNext
      }

    6.7 控制抽象

    控制抽象是一类函数:
    1、参数是函数。
    2、函数参数没有输入值也没有返回值。
     
    1)使用示例:
    def runInThread(block: () => Unit) {
      new Thread {
        override def run() { block() }
      }.start()
    }
    // 传入函数 runInThread { () => println("Hi") ; Thread.sleep(10000); println("Bye") } () = > 有些多余,可以使用换名调用来表示,省略()保留=> // 这种叫控制抽象函数 (看上去像是编程语言关键字的函数) def runInThread(block: => Unit) {   new Thread {     override def run() { block }   }.start() }
    // 优雅的传入 runInThread { println("Hi") ; Thread.sleep(1000); println("Bye") }

    //可以定义类似于
    while 的 until 函数 def until(condition: => Boolean)(block: => Unit) {   if (!condition) {     block     until(condition)(block)   } }

    var x = 10
    until (x == 0) {
      x -= 1
      println(x)
    }

    笔记:

    //6.7 控制抽象
    def runOnThread(f1:() => Unit): Unit = {
      new Thread{
        override def run(): Unit = {
          f1()
        }
      }.start()
    }
    
    runOnThread({
      () => println("干活!")
        Thread.sleep(5000)
        println("活干完了!")
    })
    
    //    () => 1; 2; 3 + 1
  • 相关阅读:
    Django入门
    Python从入门到放弃
    Python中的元类(metaclass)
    蓝鲸gse启动失败
    VS2019添加微软ReportViewer
    DevExpress WinForms各版本与 .NET、Visual Studio 的版本兼容性
    SQL语句查询每个分组的前N条记录的实现方法
    如何查看Windows安装版本号
    学习webpack
    Python3.x将代码打包成exe程序并添加图标
  • 原文地址:https://www.cnblogs.com/LXL616/p/11122087.html
Copyright © 2011-2022 走看看