闭包,和js中的闭包一样,返回值依赖于声明在函数外部的一个或多个变量,那么这个函数就是闭包函数。

    val i: Int = 20
//函数func的方法体中使用了在func外部定义的变量 那func就是个闭包函数
val func = (x: Int) => x + i

柯里化(Currying)指的是把原来接受多个参数的函数变换成接受一个参数的函数过程,并且返回接受余下的参数且返回结果为一个新函数的技术。柯里化并不是scala特有的,js中也有。

package com.zy.scala

object CurryingDemo {
def main(args: Array[String]): Unit = { //原本的方法
def m(x: Int, y: Int) = x + y //第一种柯里化
def first(x: Int) = (y: Int) => x + y val second = first(1)
val result: Int = second(2)
println(result) //第二种柯里化
def curriedSum(x: Int)(y: Int) = x + y val sum: Int = curriedSum(1)(2)
println(sum) }
}
Scala 提供的隐式转换和隐式参数功能,是非常有特色的功能。是 Java 等编程语言所没有的功能。它可以允许你手动指定,将某种类型的对象转换成其他类型的对象或者是给一个类增加方法。通过这些功能,
可以实现非常强大、特殊的功能。 Scala 的隐式转换,其实最核心的就是定义隐式转换方法,即 implicit conversion function。定义的隐式转换方法,只要在编写的程序内引入,就会被Scala 自动使用。Scala 会根据隐式转换方法的签名,
在程序中使用到隐式转换方法接收的参数类型定义的对象时,会自动将其传入隐式转换方法,转换为另外一种类型的对象并返回。这就是“隐式转换”。其中所有的隐式值和隐式方法必须放到 object 中。 然而使用 Scala 的隐式转换是有一定的限制的,总结如下:
  implicit 关键字只能用来修饰方法、变量(参数)。
  隐式转换的方法在当前范围内才有效。如果隐式转换不在当前范围内定义(比如定义在另一个类中或包含在某个对象中),那么必须通过 import 语句将其导。 所谓的隐式参数,指的是在函数或者方法中,定义一个用 implicit 修饰的参数,此时 Scala 会尝试找到一个指定类型的,用 implicit 修饰的参数,即隐式值,并注入参数。 Scala 会在两个范围内查找:
  当前作用域内可见的 val 或 var 定义的隐式变量;
  一种是隐式参数类型的伴生对象内的隐式值;

隐式参数案例

package com.zy.scala

object Company {
//在 object 中定义隐式值 注意:同一类型的隐式值只允许出现一次,否则会报错
implicit val aaa = "zhangsan"
implicit val bbb = 10000.00
} class Boss {
//注意参数匹配的类型 它需要的是 String 类型的隐式值
def callName()(implicit name: String): String = {
name + " is coming !"
} //定义一个用 implicit 修饰的参数
//注意参数匹配的类型 它需要的是 Double 类型的隐式值
def getMoney()(implicit money: Double): String = {
" 当月薪水:" + money
}
} object Boss extends App {
//使用 import 导入定义好的隐式值,注意:必须先加载否则会报错
import Company._ val boss = new Boss
println(boss.callName() + boss.getMoney())
}

隐式转换

package com.zy.scala

import java.io.File
import scala.io.Source object MyPredef {
//定义隐式转换方法
implicit def file2RichFile(file: File) = new RichFile(file)
} class RichFile(val f: File) {
def read() = Source.fromFile(f).mkString
} object RichFile {
def main(args: Array[String]) {
val f = new File("E://words.txt")
//使用 import 导入隐式转换方法
import MyPredef._
//通过隐式转换,让 File 类具备了 RichFile 类中的方法
val content = f.read()
println(content)
}
}
package com.zy.scala

class Man(val name: String)

class SuperMan(val name: String) {
def heat = print("超人打怪兽")
} object SuperMan {
//隐式转换方法
implicit def man2SuperMan(man: Man) = new SuperMan(man.name) def main(args: Array[String]) {
val hero = new Man("hero")
//Man 具备了 SuperMan 的方法
hero.heat
}
}
package com.zy.scala

class A(c: C) {
def readBook(): Unit = {
println("A 说:好书好书...")
}
} class B(c: C) {
def readBook(): Unit = {
println("B 说:看不懂...")
} def writeBook(): Unit = {
println("B 说:不会写...")
}
} class C object AB {
//创建一个类的 2 个类的隐式转换
implicit def C2A(c: C) = new A(c) implicit def C2B(c: C) = new B(c)
} object B {
def main(args: Array[String]) {
//导包
//1. import AB._ 会将 AB 类下的所有隐式转换导进来
//2. import AB._C2A 只导入 C 类到 A 类的的隐式转换方法
//3. import AB._C2B 只导入 C 类到 B 类的的隐式转换方法
import AB._
val c = new C
//由于 A 类与 B 类中都有 readBook(),只能导入其中一个,否则调用共同方法时代码报错
//c.readBook()
//C 类可以执行 B 类中的 writeBook()
c.writeBook()
}
}

Scala基础:闭包、柯里化、隐式转换和隐式参数的更多相关文章

  1. Scala中的柯里化

    一.初识Currying柯里化   柯里化(Currying)技术 Christopher Strachey 以逻辑学家 Haskell Curry 命名的(尽管它是 Moses Schnfinkel ...

  2. Scala 学习之路(十)—— 函数 & 闭包 & 柯里化

    一.函数 1.1 函数与方法 Scala中函数与方法的区别非常小,如果函数作为某个对象的成员,这样的函数被称为方法,否则就是一个正常的函数. // 定义方法 def multi1(x:Int) = { ...

  3. Scala 系列(十)—— 函数 & 闭包 & 柯里化

    一.函数 1.1 函数与方法 Scala 中函数与方法的区别非常小,如果函数作为某个对象的成员,这样的函数被称为方法,否则就是一个正常的函数. // 定义方法 def multi1(x:Int) = ...

  4. 理解运用JS的闭包、高阶函数、柯里化

    JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...

  5. JS的闭包、高阶函数、柯里化

    本文原链接:https://cloud.tencent.com/developer/article/1326958 https://cloud.tencent.com/developer/articl ...

  6. 【 js 基础 】【 源码学习 】柯里化和箭头函数

    最近在看 redux 的源码,代码结构很简单,主要就是6个文件,其中 index.js 负责将剩余5个文件中定义的方法 export 出来,其他5个文件各自负责一个方法的实现. 大部分代码比较简单,很 ...

  7. 浅析 JavaScript 中的 函数 currying 柯里化

    原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...

  8. JS 柯里化 (curry)

    用 JS 理解柯里化 函数式编程风格,试图以函数作为参数传递(回调)和无副作用的返回函数(修改程序的状态). 很多语言采用了这种编程风格.JavaScript,Haskell,Clojure,Erla ...

  9. Scala学习二十一——隐式转换和隐式参数

    一.本章要点 隐式转换用于类型之间的转换 必须引入隐式转换,并确保它们可以以单个标识符的形式出现在当前作用域 隐式参数列表会要求指定类型的对象.它们可以从当前作用域中以单个标识符定义的隐式对象的获取, ...

  10. JavaScript中的柯里化

    转载自:https://www.cnblogs.com/zztt/p/4142891.html 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Ha ...

随机推荐

  1. bat命令1

    echo 命令 打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo命令将显示当前回显设置. 语法 echo [{on|off}] [message] Sample:@echo off ...

  2. functool.wraps and functools.partial

    functools.partial 通过包装手法,允许我们 "重新定义" 函数签名.  通常是将函数的部分参数给固定下来, 从而形成一个输入参数更少的新函数. functool.w ...

  3. 13 Stream Processing Patterns for building Streaming and Realtime Applications

    原文:https://iwringer.wordpress.com/2015/08/03/patterns-for-streaming-realtime-analytics/ Introduction ...

  4. 几个开源ssg 技术方案

    1. Nanoc    2. Middle Man App   3. Hexo   4. DocPad   5. Hugo   6. Jekyll   7. Octopress   8. Harp   ...

  5. php替换 json符号

  6. CDN初学搭建(ats)

    CDN初学搭建(ats) ats trafficserver squid 一. CDN初学搭建 准备vagrant virtualbox 内部环境测试所需包 一.vagrant创建启动虚拟机 1 mk ...

  7. Redis简单介绍与安装

    Redis是一个开源,高级的键值存储和一个适用的解决方案,用于构建高性能,可扩展的Web应用程序. Redis有三个主要特点,使它优越于其它键值数据存储系统 - 1) Redis将其数据库完全保存在内 ...

  8. java 工作流

    BPM是jboss旗下遵守LGPL许可的java开源工作流,功能比较完善,从4.0开始引入了pvm的概念,支持jPDL.BPEL等流程定义语言.由于相关资料还比较少,开发自己的一个demo还不是太容易 ...

  9. Linux 制作补丁 打补丁 撤销补丁

    1.制作补丁 diff - 逐行比较文件 格式 diff   参数   旧文件/旧文件夹   新文件/新文件夹 -N   将不存在的文件看作是空的 -a   将所有文件都视为文本文件 -u   以合并 ...

  10. 关于不同应用程序存储IO类型的描述

    介绍 存储系统作为数据的载体,为前端的服务器和应用程序提供读写服务.存储阵列某种意义上来说,是对应用服务器提供数据服务的后端“服务器”.应用服务器对存 储系统发送数据的“读”和“写”的请求.然而,不同 ...