有时候咱们看scala代码的时候,会发现明明没有这个类的类型或者函数,甚至是没有这个类,编译器不仅没有报错,程序还能够失常运行,其实这里就用到了scala的隐式转换。

隐式函数

当咱们调用一个对象的办法的时候,然而这个对象并没有这个办法,此时就会触发隐式转换,会把这个对象偷偷的转换为具备这个办法的对象。
比方上面的例子,小鸡能够走路也能够跑,然而它也想像小鸟一样飞,然而它有没有这个性能。咱们能够在不对小鸡整改的根底上,引入ChickenImplicit,让小鸡能够隐式的调用Bird的fly办法,让它能够像小鸟一样飞。

object ImplicitDemo1 {  def main(args: Array[String]): Unit = {    import ChickenImplicit._    val chicken = new Chicken()    chicken.work()    chicken.run()    // 隐式转为Bird,并调用Bird的fly办法    chicken.fly()  }}class Chicken() {  def work(): Unit = {    println("小鸡在走")  }  def run(): Unit = {    println("小鸡在跑")  }}class Bird {  def fly(): Unit = {    println("小鸟在飞")  }}object ChickenImplicit {  implicit def chicken2Bird(c: Chicken): Bird = new Bird()}

下面是额定的定义ChickenImplicit,然而有时候咱们能够间接在同一个类里定义,这样局不必加import,具体用哪种还是要看理论场景。

object ImplicitDemo2 {  def main(args: Array[String]): Unit = {    val chicken = new Chicken2()    chicken.work()    chicken.run()    // 隐式转为Bird,并调用Bird的fly办法    chicken.fly()  }  implicit def chicken2Bird(c: Chicken2): Bird2 = new Bird2()}class Chicken2() {  def work(): Unit = {    println("小鸡在走")  }  def run(): Unit = {    println("小鸡在跑")  }}class Bird2 {  def fly(): Unit = {    println("小鸟在飞")  }}

隐式参数

比方咱们要调用办法,打印咱们传递的参数,咱们是这样写的:

def main(args: Array[String]): Unit = {    printInfo1("aaa") // aaa}def printInfo1(str: String): Unit = {    println(str)}

如果咱们调用办法的时候,如果不想传递参数,咱们能够这样:
在办法里指定默认值

def main(args: Array[String]): Unit = {    printInfo2("bbb") // bbb    printInfo2() // default}def printInfo2(str: String = "default"): Unit = {    println(str)}

如果通过隐式参数,那咱们就能够这样:
这里的办法不加括号也是能够的。因为是通过类型来匹配隐式值的,所以在一个作用域中,同一个类型只能有一次,并且他的优先级高于默认的,所以没有传递参数的时候,打印的implicit。

def main(args: Array[String]): Unit = {    implicit val str: String = "implicit"    printInfo3("ccc") // ccc    printInfo3() // default    printInfo3 // implicit}def printInfo3(implicit str: String = "default"): Unit = {    println(str)}

总结

当咱们须要隐式转换的时候,咱们就须要用implicit关键字。
隐式转换的时候,他会先全局的查找是否有匹配的办法或者参数,如果没有再思考隐式转换。
因为隐式参数是依据类型的,所以同一作用域不能定义多个同一个类型的,并且默认值是优先于默认的。