Implicit conversion of scala

Keywords: MySQL Scala

1. Implicit Conversion

1 Basic Introduction

Implicit conversion functions are functions declared with a single parameter using the implicit keyword.This function is automatically applied to convert values from one type to another

(2) Examples

object ImplicitDemo01 {
  def main(args: Array[String]): Unit = {

    //Write an implicit function to double->Int conversion
    //Implicit functions should be in scope to take effect
    implicit def f1(d:Double): Int = { //Bottom generation f1$1
      d.toInt
    }

    val num: Int = 3.5 // Bottom level compilation f1$1 (3.5)//idea u_
    println("num =" + num)

  }
}

3. Attention to detail

  1. The function name of an implicit conversion function can be arbitrary. Implicit conversion is not related to the function name, but only to the function signature (function parameter type and return value type).

  2. Implicit functions can have more than one (i.e., an implicit function list), but you need to ensure that only one implicit function can be identified in the current environment

object ImplicitDemo01 {
  def main(args: Array[String]): Unit = {

    //Write an implicit function to double->Int conversion
    //Implicit functions should be in scope to take effect
    implicit def f1(d:Double): Int = { //Bottom generation f1$1
      d.toInt
    }

    implicit def f2(f:Float): Int = {
      f.toInt
    }

    //Here we must ensure that the matching of implicit functions is only unique.
//    implicit def f3(f1:Float): Int = {
//      f1.toInt
//    }


    val num: Int = 3.5 // Underlying compilation f1 (3.5)
    val num2: Int = 4.5f //
    println("num =" + num)
  }
}

2. Implicit Conversion Enriches Class Library Functions

1 Example

Dynamic addition of delete methods to MySQL classes using implicit conversion

object ImplicitDemo02 {

  def main(args: Array[String]): Unit = {

    //Write an implicit function to enrich mySQL functionality
    implicit def addDelete(msql:MySQL): DB = {
      new DB
    }

    //Create mysql object
    val mySQL = new MySQL
    mySQL.insert()
    mySQL.delete() // Compiler job analysis addDelete (mySQL).delete()
    mySQL.update()

  }
}

class MySQL {
  def insert(): Unit = {
    println("insert")
  }
}

class DB {
  def delete(): Unit = {
    println("delete")
  }

  def update(): Unit = {
    println("update")
  }
}

class Dog {
}


3. Implicit Value

1 Basic Introduction

Implicit values, also known as implicit variables, mark a parameter variable as implicit, so the compiler searches for implicit values in the scope as default parameters when the method omits the implicit parameters

(2) Examples

object ImplicitValDemo03 {
  def main(args: Array[String]): Unit = {

    implicit val str1: String = "jack~" //This is the implicit value

    //implicit name: String:name is the implicit parameter
    def hello(implicit name: String): Unit = {
      println(name + " hello")
    }

    hello //Bottom hello (str1);

  }
}

3 Example 2
Explain implicit value, default value, priority of value passed

//Summary
//1. When in the program, there are also implicit values, default values, pass values
//2. Compiler priority is Pass-by > Implicit > Default
//3. There must be no ambiguity in implicit value matching
//4. If none of the three (implicit, default, pass-by) values are present, an error will occur

object ImplicitVal02 {
  def main(args: Array[String]): Unit = {
    // Implicit variable (value)
//    implicit val name: String = "Scala"
    //implicit val name1: String = "World"

    //Implicit parameters
    def hello(implicit content: String = "jack"): Unit = {
      println("Hello " + content)
    } //Call hello
    hello

    //When both implicit and default values exist, implicit takes precedence
    def hello2(implicit content: String = "jack"): Unit = {
      println("Hello2 " + content)
    } //Call hello
    hello2


    //Explain
    //1. When an implicit parameter does not match the implicit value, the default value will still be used

    implicit val name: Int = 10
    def hello3(implicit content: String = "jack"): Unit = {
      println("Hello3 " + content)
    } //Call hello
    hello3 //  hello3 jack

    //Error occurs when there are no implicit values, no default values, and no passed values
    def hello4(implicit content: String ): Unit = {
      println("Hello4 " + content)
    } //Call hello
    hello4 //  hello3 jack
  }
}

4. Implicit Classes

1 Basic Introduction

Implicit classes are available after scala 2.10. Implicit classes can be declared using implicit. Implicit classes are very powerful and can also extend the functionality of classes. Implicit classes play an important role in collections because they are more convenient to enrich library functionality than the previous implicit conversion.

(2) Characteristics of implicit classes

  1. It has one and only one construction parameter
  2. Implicit classes must be defined in "classes" or "companion objects" or "package objects", that is, they cannot be top-level objects.
  3. Implicit classes cannot be sample classes
  4. Cannot have an identifier with the same name in the scope

(3) Examples

object ImplicitClassDemo {

  def main(args: Array[String]): Unit = {
    //DB1 generates an implicit class for the corresponding
    //DB1 is an implicit class, when we create an instance of MySQL1 within the scope of that implicit class
    //The implicit class will take effect and the compiler will still complete the work
    //Look at the bottom..
    implicit class DB1(val m: MySQL1) { //ImplicitClassDemo$DB1$2
      def addSuffix(): String = {
        m + " scala"
      }
    }
    

    //Create an instance of MySQL1
    val mySQL = new MySQL1 
    mySQL.sayOk() //itself
    mySQL.addSuffix() //Study how to associate DB1 (mySQL).addSuffix();

  }
}

class DB1 {}


class MySQL1 {
  def sayOk(): Unit = {
    println("sayOk")
  }
}

5. Implicit conversion timing

1) When the type of parameter in the method is inconsistent with the target type, Or when assigning a value.
 implicit def f1(d:Double): Int = {
      d.toInt
    } 

    def test1(n1:Int): Unit = {
      println("ok")
    }
    test1(10.1)

2) When an object calls a method or member that does not exist in its class, the compiler automatically implicitly converts the object (by type)

6. Implicit Resolution Mechanism

That is, how the compiler finds missing information, and parsing has two rules:

  1. Implicit entities (implicit methods, implicit classes, implicit objects) are first found under the current code scope.(This is generally the case

  2. If the first rule fails to find an implicit entity, it continues to look in the scope of the type of the implicit parameter.The scope of a type refers to all the associated modules associated with that type, and the type T of an implicit entity has the following search scope (the second should be avoided when used in a wide and complex context):

a) If T is defined as T with A with B with C, A,B,C are all parts of T, and their associated objects are searched during the implicit resolution of T.

b) If T is a parameterized type, then both the type parameter and the part associated with the type parameter count as the part of T, such as the implicit search for List[String] searches for the companion objects of List and the companion objects of String.

c) If T is a singleton type p.T, that is, T belongs to a p object, then the P object will also be searched.

d) If T is a type injection S#T, both S and T will be searched

7. Rules to follow when implicitly converting

1) Ambiguity cannot exist
2) Implicit operations cannot be nested // [Example:] For example: Implicit conversion function

object ImplicitNotice {
  def main(args: Array[String]): Unit = {

    //1. Implicit conversion cannot be ambiguous
    //2. Implicit conversion cannot be nested

    implicit def f1(d: Double): Int = {
      d.toInt
      //val num2:Int = 2.3 //underlying f1$1 (2.3)//f1$1 corresponds to f1, which is recursive
    }

    val num1: Int = 1.1
  }
}

Posted by hasjem on Fri, 16 Aug 2019 20:16:53 -0700