在scala中,经常会遇到implicit关键字,这是个非常神奇的功能,但是不了解用法就会觉得代码混乱难懂。今天来简单记录下他的用法。
implicit主要有三种用法:
- 隐式函数
我们先来讲下隐式函数。隐式转换函数是指在同一个作用域下面,一个给定输入类型并自动转换为指定返回类型的函数,这个函数和函数名字无关,和入参名字无关,只和入参类型以及返回类型有关。注意是同一个作用域。
假设我们有个函数sayHello(s: String)。但是我们想要在一个Int上使用该函数,那么定义个从Int=>String的隐式函数就可以,例如:
implicit def convertInt2String(i: Int) = i.toString
这样就可以直接sayHello(5)这样用。
- 隐式参数
再来讲讲隐式参数,这个是蛮神奇的一个功能我觉得。有空要研究下原理。隐式参数的作用是指如果有一个函数(一般是currying函数)定义包含一个隐式的参数,那么你需要一个隐式的同类型变量,在调用该函数的时候你不需要显示调用这个参数,scala会帮你把隐式变量作为参数传进去。例如:
implicit def param: T = T()
def function(s: String)(implicit t: T)
function("param1") // == function("param1")(param)
- 隐式类
隐式类作用类似隐式函数,隐式函数是将类型转换。而隐式类则是在某对象(变量)未定义相应方法的时候,若定义了该类型的隐式类,并且包含该方法,则调用隐式类的方法。例如:
import scala.io.Source
import java.io.File
object ImplicitClass {
import Context._
def main(args: Array[String]) {
1.add(2) // 在当前作用域中寻找 将Int(1) 作为变量的类同时具有add 的方法的类,如有,则执行
new File("/home/resources/file.txt").read() // 在当前作用域中寻找 将File 作为变量的类同时具有read的方法的类,如有,则执行
}
}
object Context{
implicit class ConvertInt(inst: Int){
def add(tmp: Int) = inst + tmp
}
implicit class FileEnhance(file: File){
def read() = Source.fromFile(file.getPath).mkString
}
}