Scala Implicit Parameters函数
若是定义函数时,标明某一参数为implicit,则这个参数是隐式参数。看起来与缺省参数(Default Parameters)相似,调用者没必要在调用时指定该参数。spa
可是就实际运行机制而言,隐式参数与缺省参数是彻底不同的。缺省参数是函数定义方设定了一个缺省值,在调用者没有指明时将使用该缺省值。 隐式参数则不一样,最终是会由调用方指定参数值,只是不必定在调用的语句里指定而已。编译器在发现缺乏隐式参数时,会在程序范围内寻找符合类型的隐式值,若是找不到则编译会失败。scala
以下代码,code
abstract class Logger { def log(s: String) } class FileLogger extends Logger { def log(s: String) { println("Log in file: " + s) } } class StdoutLogger extends Logger { def log(s: String) { println("Stdout: " + s) } } def Add(a: Int, b: Int)(implicit logger: Logger) { val sum = a + b logger.log("%d + %d = %d".format(a, b, sum)) } implicit val log = new FileLogger Add(1, 2) Add(2, 3)(new StdoutLogger) //you may do it explicitly
运行并输出,orm
C:\WorkSpace6-scala\scala-train\src\com\usoft>scala implicit_parameter.scalablog
Log in file: 1 + 2 = 3继承
Stdout: 2 + 3 = 5ci
若是上述代码没有implicit val log = new FileLogger这一句,在代码范围内也没有其余的Logger类型的implicit值,编译器会报错:编译器
could not find implicit value for parameter logger: com.scalass.examples.blog.ImplicitParameters.Loggerit
反之,若是能找到Logger类型的隐式值,编译器会将该隐式值做为参数传递过去。
与隐式转换同样,你也能够选择显示的传递隐式参数,实际上编译器就是这样作的,在程序上下文找到符合类型要求的隐式值,将它显示的做为参数传递。 也与隐式转换同样,隐式值的名称对编译器并没有影响,只要类型符合便可,可是为了可读性,建议赋予它合适的名称。
到这里可能你会有些想法了,其实一样的功能可能能够由依赖注入等方式实现。在使用依赖注入,或是继承等方式能实现的状况下,咱们不建议使用隐式转换或隐式参数。 由于其余的方式,代码结构可能会更清晰,而过多的使用隐式转换或隐式参数经常会让读者摸不着头脑。
============END============