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 ...
随机推荐
- LeetCode 549. Binary Tree Longest Consecutive Sequence II
原题链接在这里:https://leetcode.com/problems/binary-tree-longest-consecutive-sequence-ii/description/ 题目: G ...
- 性能指标术语&理发店模型
2015-11-26 09:13:53 响应时间 响应时间=呈现时间+系统响应时间 呈现时间取决于数据在被客户端收后到呈现出页面所消耗的时间: 系统响应时间指应用系统从请求发出开始到客户端接收到数据所 ...
- UNIX简化路径
Given an absolute path for a file (Unix-style), simplify it. For example, path = “/home/”, => “/h ...
- Oracle删除主键约束的同时删除索引
继续昨天的折腾(Oracle修改主键约束),删掉主键约束后,发现唯一索引并未删掉.仔细看了下,主键约束跟唯一索引名称不一样,这说明是先创建了唯一索引,后创建的主键约束.我们来试验下: SQL> ...
- git 修改提交说明 commit message
修改最近一次的提交说明 1.代码未推送到远程服务器 $ git commit --amend 此指令会打开文本编辑器,第二行就是提交说明,修改完后按 ctrl+x 退出,后面根据提示操作. 2.代码已 ...
- wdlinux重新编译nginx
背景: 由于web站点需要换主机,并且切换环境. 站点需要做反相代理(nginx),主机从美国迁移到香港[考虑到速度问题,为什么不用大陆阿里云ECS服务器?几十个域名备案麻烦,还有阿里云内地没有多ip ...
- linux命令之awk
简介 awk命令的名称是取自三位创始人Alfred Aho .Peter Weinberger 和 Brian Kernighan姓名的首字母,awk有自己的程序设计语言,设计简短的程序,读入文件,数 ...
- 学习FPGA过程中的理论知识
学习FPGA,先要有数电知识,最好有点C语言,,学好硬件描述语言,verilog或者vhdl.在有这些基础上,做一些小的模块不断积累.这里不再赘述. 下面介绍一下关于FPGA学习过程中的一些理论知识. ...
- Java-Runoob-高级教程:Java 数据结构
ylbtech-Java-Runoob-高级教程:Java 数据结构 1.返回顶部 1. Java 数据结构 Java工具包提供了强大的数据结构.在Java中的数据结构主要包括以下几种接口和类: 枚举 ...
- cx_Oracle.DatabaseError: ORA-12541: TNS:no listener
问题:利用Python连接Oracle时报错,完整过程如下 import cx_Oracle conn = cx_Oracle.connect('testma/dingjia@192.168.88.1 ...