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 ...
随机推荐
- 电源lc滤波及单点接地(转载)
1.在一个高速数字电路设计里面,看到在电源部分进行了如下的处理.不过怎么都不能理解,如果说1uF和0.1uF电容并联,这块处理是一个经验值.那么前面的LC滤波参数,参数又是如何确定的?DVDD-in输 ...
- BZOJ4145 [AMPPZ2014]The Prices
题意 你要购买m种物品各一件,一共有n家商店,你到第i家商店的路费为d[i],在第i家商店购买第j种物品的费用为c[i][j],求最小总费用. \(n \leq 100,m \leq 16\) 分析 ...
- Bootstrap组件福利篇:十二款好用的组件推荐
阅读目录 一.时间组件 1.效果展示 2.源码说明 3.代码示例 二.自增器组件 1.效果展示 2.源码说明 3.代码示例 三.加载效果 一.实用型 二.炫酷型 四.流程图小插件 1.效果展示 2.源 ...
- oralce之 10046对Hash Join分析
前两天解决了一个优化SQL的case,SQL语句如下,big_table为150G大小,small_table很小,9000多条记录,不到1M大小,hash_area_size, sort_area_ ...
- BZOJ4974:[lydsy1708月赛]字符串大师
浅谈\(KMP\):https://www.cnblogs.com/AKMer/p/10438148.html 题目传送门:https://lydsy.com/JudgeOnline/problem. ...
- java.lang.NoSuchFieldError: TRACE
Exception in thread "main" java.lang.NoSuchFieldError: TRACE at org.jboss.logging.Log4j ...
- Windows10+CUDA8.0+VS2015+CUDNN5下配置caffe
[转]https://blog.csdn.net/zhj_matlab/article/details/69943869
- “FPGA+云"助力高性能计算
用AI防鲨鱼.用AI学写中国书法.用AI预测人类死亡时间.用AI审判罪犯……在人工智能方兴未艾的今天,越来越廉价和普及的AI领域真的是什么都不值钱,除了想象力.那在这无所不能的AI盛世,一定没道理让算 ...
- struts2学习(9)struts标签2(界面标签、其他标签)
四.struts2界面标签: 五.其他标签: 1.界面标签: uiTag.jsp: <body> <h>界面标签</h> <hr/> <a hre ...
- java代码---------实现File的目录下创建文本文档
总结:虽然他没教给我们很多,但是他已经很棒了 package com.a.b; import java.io.*; public class dd { public static void main( ...