zoukankan      html  css  js  c++  java
  • Scala 基础(十二):Scala 函数式编程(四)高级(二)参数(类型)推断、闭包(closure)、函数柯里化(curry)、控制抽象

    1  参数(类型)推断

    参数推断省去类型信息(在某些情况下[需要有应用场景],参数类型是可以推断出来的,如list=(1,2,3) list.map() map中函数参数类型是可以推断的),同时也可以进行相应的简写

    参数类型推断写法说明

    1)参数类型是可以推断时,可以省略参数类型

    2)当传入的函数,只有单个参数时,可以省去括号

    3)如果变量只在=>右边只出现一次,可以用_来代替

    应用案例

    //分别说明
    val list = List(1, 2, 3, 4)
    println(list.map((x:Int)=>x + 1)) //(2,3,4,5)
    println(list.map((x)=>x + 1))
    println(list.map(x=>x + 1))
    println(list.map(_ + 1))
    val res = list.reduce(_+_)

    应用案例的小结

    1)map是一个高阶函数,因此也可以直接传入一个匿名函数,完成map

    2)当遍历list时,参数类型是可以推断出来的,可以省略数据类型Int println(list.map((x)=>x + 1))

    3)当传入的函数,只有单个参数时,可以省去括号 println(list.map(x=>x + 1))

    4)如果变量只在=>右边只出现一次,可以用_来代替 println(list.map(_ + 1))

    2  闭包(closure)

    基本介绍:闭包就是一个函数和与其相关的引用环境组合的一个整体(实体)。

    //1.用等价理解方式改写 2.对象属性理解
    def minusxy(x: Int) = (y: Int) => x - y
    //f函数就是闭包.
    val f = minusxy(20) 
    println("f(1)=" + f(1)) // 19
    println("f(2)=" + f(2)) // 18

    1)第1点 (y: Int) => x – y

    返回的是一个匿名函数 ,因为该函数引用到到函数外的 x,那么 该函数和x整体形成一个闭包

    如:这里 val f = minusxy(20) 的f函数就是闭包

    2)你可以这样理解,返回函数是一个对象,而x就是该对象的一个字段,他们共同形成一个闭包

    3)当多次调用f时(可以理解多次调用闭包),发现使用的是同一个x, 所以x不变。

    4)在使用闭包时,主要搞清楚返回函数引用了函数外的哪些变量,因为他们会组合成一个整体(实体),形成一个闭包

    闭包的好处

    1)返回的匿名函数和 makeSuffix (suffix string) 的 suffix 变量 组合成一个闭包,因为 返回的函数引用到suffix这个变量

    2)我们体会一下闭包的好处,如果使用传统的方法,也可以轻松实现这个功能,但是传统方法需要每次都传入 后缀名,比如 .jpg ,而闭包因为可以保留上次引用的某个值,所以我们传入一次就可以反复使用。大家可以仔细的体会一把!

    3  函数柯里化(curry)

    1)函数编程中,接受多个参数的函数都可以转化为接受单个参数的函数,这个转化过程就叫柯里化

    2)柯里化就是证明了函数只需要一个参数而已。其实我们刚才的学习过程中,已经涉及到了柯里化操作。

    3)不用设立柯里化存在的意义这样的命题。柯里化就是以函数为主体这种思想发展的必然产生的结果。(即:柯里化是面向函数思想的必然产生结果)

    函数柯里化快速入门

    编写一个函数,接收两个整数,可以返回两个数的乘积,要求:

    使用常规的方式完成 使用闭包的方式完成 使用函数柯里化完成

    //说明
    def mul(x: Int, y: Int) = x * y
    println(mul(10, 10))
    
    def mulCurry(x: Int) = (y: Int) => x * y
    println(mulCurry(10)(9))
    
    def mulCurry2(x: Int)(y:Int) = x * y
    println(mulCurry2(10)(8))

    4 控制抽象

    如何实现将一段代码(从形式上看),作为参数传递给高阶函数,在高阶函数内部执行这段代码. 其使用的形式如 breakable{} 。

    var n = 10
    breakable {
    while (n <= 20) {
    n += 1
    if (n == 18) {
      break()
    }
    }
    }

    控制抽象基本介绍

    控制抽象是这样的函数,满足如下条件

    1)参数是函数

    2)函数参数没有输入值也没有返回值

    def myRunInThread(f1: () => Unit) = {
          new Thread {
            override def run(): Unit = {
              f1()
            }
          }.start()
        }
        myRunInThread {
          () => println("干活咯!5秒完成...")
            Thread.sleep(5000)
            println("干完咯!")
        }

    简化处理,省略(),如下形式

    进阶用法:实现类似while的until函数

  • 相关阅读:
    INVALID_STATE_ERR: DOM Exception 11
    测试用户的网络环境
    CentOS修改IP、DNS、网关
    读《结网》
    命名函数表达式
    JavaScript中的编码函数
    linux下C程序printf没有立即输出的问题及我的Makefile文件
    学习使用vimperator
    thinkpad e40 安装 nvidia显卡驱动之后
    fedora:在命令行下删除文件到回收站
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/13260300.html
Copyright © 2011-2022 走看看