Scala基础:闭包、柯里化、隐式转换和隐式参数
闭包,和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基础:闭包、柯里化、隐式转换和隐式参数的更多相关文章
- Scala中的柯里化
一.初识Currying柯里化 柯里化(Currying)技术 Christopher Strachey 以逻辑学家 Haskell Curry 命名的(尽管它是 Moses Schnfinkel ...
- Scala 学习之路(十)—— 函数 & 闭包 & 柯里化
一.函数 1.1 函数与方法 Scala中函数与方法的区别非常小,如果函数作为某个对象的成员,这样的函数被称为方法,否则就是一个正常的函数. // 定义方法 def multi1(x:Int) = { ...
- Scala 系列(十)—— 函数 & 闭包 & 柯里化
一.函数 1.1 函数与方法 Scala 中函数与方法的区别非常小,如果函数作为某个对象的成员,这样的函数被称为方法,否则就是一个正常的函数. // 定义方法 def multi1(x:Int) = ...
- 理解运用JS的闭包、高阶函数、柯里化
JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...
- JS的闭包、高阶函数、柯里化
本文原链接:https://cloud.tencent.com/developer/article/1326958 https://cloud.tencent.com/developer/articl ...
- 【 js 基础 】【 源码学习 】柯里化和箭头函数
最近在看 redux 的源码,代码结构很简单,主要就是6个文件,其中 index.js 负责将剩余5个文件中定义的方法 export 出来,其他5个文件各自负责一个方法的实现. 大部分代码比较简单,很 ...
- 浅析 JavaScript 中的 函数 currying 柯里化
原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...
- JS 柯里化 (curry)
用 JS 理解柯里化 函数式编程风格,试图以函数作为参数传递(回调)和无副作用的返回函数(修改程序的状态). 很多语言采用了这种编程风格.JavaScript,Haskell,Clojure,Erla ...
- Scala学习二十一——隐式转换和隐式参数
一.本章要点 隐式转换用于类型之间的转换 必须引入隐式转换,并确保它们可以以单个标识符的形式出现在当前作用域 隐式参数列表会要求指定类型的对象.它们可以从当前作用域中以单个标识符定义的隐式对象的获取, ...
- JavaScript中的柯里化
转载自:https://www.cnblogs.com/zztt/p/4142891.html 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Ha ...
随机推荐
- 关于python中的循环
参考下面这一篇: http://www.cnblogs.com/vamei/archive/2012/05/30/2526357.html 其中用range的方式最好!
- container-diff 谷歌开源镜像分析工具使用
1. 安装 curl -LO https://storage.googleapis.com/container-diff/latest/container-diff-linux-amd64 & ...
- web 调试工具docker的安装使用
1. weinre 工具 docker run -d -p 8080:8080 beevelop/weinre 2. vorlonjs(不支持https) docker run --name v ...
- 原生 Javascript 编写五子棋
原文地址:原生 Javascript 编写五子棋 博客地址:http://www.extlight.com 一.背景 近一个月没写 Javascript 代码,有点生疏.正好浏览网页时弹出五子棋的游戏 ...
- Ubuntu下手动安装Nvidia显卡驱动
1. 下载最新版的nVidia驱动. http://www.nvidia.com/page/drivers.html 2.编辑blacklist.conf. sudo gedit /etc/modpr ...
- 执行npm install报错:npm ERR! code EINTEGRITY
命令行执行npm install报错如下: D:\frontend\viewsdev>npm install npm ERR! code EINTEGRITY npm ERR! sha512-8 ...
- ubuntu :扩充虚拟机的磁盘容量
前言: 开始建立虚拟机的时候给的容量是20G,给了10G的交换空间,所以后来有点不够用了,现在安装软件会出现提示磁盘空间不足,所以需要扩充一下磁盘的容量. 步骤: 1.因为我用的是Vmware ...
- Proxool抛出的警告 was active for 365172 milliseconds and has been removed automaticaly
WARN cetDB:149 - #0005 was active for 365172 milliseconds and has been removed automaticaly. The Thr ...
- linux下进程cpu占用过高问题定位方法
背景 记得前段时间,同事说他们测试环境的服务器cpu使用率一直处于100%,本地又没有什么接口调用,为什么会这样?cpu使用率居高不下,自然是有某些线程一直占用着cpu资源,那又如何查看占用cpu较高 ...
- 3dmax卡通渲染插件pencil+渲染线框
转自:http://www.cr173.com/soft/179512.html http://www.psoft.co.jp/jp/ 官网和YTB有 2代的视频教程,平均每个2分钟长,无解说,是日文 ...