闭包,和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() } }