Sometimes when we look at the scala code, we will find that there is no type or function of this class, or even no such class. Not only does the compiler report no errors, but the program can run normally. In fact, the implicit conversion of scala is used here.

Implicit function

When we call a method of an object, but the object does not have this method, an implicit conversion will be triggered at this time, and the object will be secretly converted into an object with this method.
For example, in the following example, a chicken can walk or run, but it also wants to fly like a bird, but does it have this function? We can introduce ChickenImplicit on the basis of not correcting the chicken, so that the chicken can implicitly call Bird's fly method, so that it can fly like a bird.

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()
}

The above is an additional definition of ChickenImplicit, but sometimes we can directly define it in the same class, so that the bureau does not need to add import, which depends on the actual scenario.

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("小鸟在飞")
  }
}

Implicit parameter

For example, if we want to call a method and print the parameters we pass, we write it like this:

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

def printInfo1(str: String): Unit = {
    println(str)
}

If we don't want to pass parameters when calling the method, we can do this:
Specify the default value in the method

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

def printInfo2(str: String = "default"): Unit = {
    println(str)
}

If implicit parameters are passed, then we can do this:
The method here is also possible without parentheses. Because the implicit value is matched by type, the same type can only be used once in a scope, and its priority is higher than the default, so when no parameters are passed, the implicit value is printed.

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)
}

to sum up

When we need implicit conversion, we need to use the implicit keyword.
During implicit conversion, he will first find out whether there is a matching method or parameter globally, and then consider implicit conversion if there is no matching method or parameter.
Since implicit parameters are based on type, the same scope cannot define multiple of the same type, and the default value takes precedence over the default.


大军
847 声望183 粉丝

学而不思则罔,思而不学则殆


下一篇 »
Scala - 泛型

引用和评论

0 条评论