Scala(五)隐式转换

  1. 隐式转换Scala编译器在编译器在进行类型匹配的时候找不到该类型,那么隐式转换就成为了一种途径来告诉编译器如何将当前的类型转换成预期的类型。隐式转换函数时Scala自动调用的。语法为在变量、方法或者类的前边用implicit修饰。

    1. 隐式转换满足的规则
      1. 作用域规则:Scala编译值只考虑处于作用域的隐式转换函数。隐式转换要么是单一标识符的形式,出现在作用域中,或者是存在于源类型或者目标类型的伴生对象中。如果隐式转换不在当前作用域定义,如果需要使用必须使用import将其导入。如果当前作用域出现了相同的签名隐式转换,那么编译器就会报错
      2. 单一调用规则:编译器在同一个地方只会添加一次隐式操作,不会再添加一个隐式操作之后再此基础上再次添加隐式操作
      3. 显示操作先行规则:如果编写的代码类型检查无误,那么不会触发任何隐式转换
    2. 触发隐式转换的条件
      1. 调用某个函数,但是传入的参数类型与函数的参数类型不匹配就会出发隐式转换
      2. 使用某个类的时候,调用该类没有的方法的时候
      3. 使用某个类,虽然类中存在这个方法,但是我们传入的参数一方法参数不匹配的时候
    3. 隐式转换的机制:
      1. 当前左右内查找隐式转换
      2. 如果T被定义为T with A with B with C,那么A,B,C都是T的部分,在T的隐式解析过程中,它们的伴生对象都会被搜索
      3. 如果T是参数化类型,那么类型参数和与类型参数相关联的部分都算作T的部分,比如List[String]的隐式搜索会搜索List的伴生对象和String的伴生对象
      4. 如果T是一个单例类型p.T,即T是属于某个p对象内,那么这个p对象也会被搜索
      5. 如果T是个类型注入S#T,那么S和T都会被搜索
    4. 隐式转换的例子

      1. 当前作用域定义隐式转换

        package com.lyz.scala.five
        
        object ImplicitLearn {
          def main(args: Array[String]): Unit = {
            //1.定义一个隐式转换
            implicit def integer2string(arg: Int): String = {
              arg.toString
            }
        
            //2.定一个参数为String的函数
            def hello(name: String): Unit = {
              println(name)
            }
        
            //3.利用隐式转换将参数适配函数的参数类型
            hello(1000)
        
            //通过隐式转换增强了Studen1234这个类的功能
            implicit def stu2tea(student1234: Student1234): Teacher1234 ={
              new Teacher1234()
            }
          }
        }
        package com.lyz.scala.five
        
        object ImplicitLearn {
          def main(args: Array[String]): Unit = {
            //通过隐式转换增强了Studen1234这个类的功能
            implicit def stu2tea(student1234: Student1234): Teacher1234 ={
              new Teacher1234()
            }
        
            val student1234  = new Student1234
            student1234.teach()//增强了teach功能
          }
        }
        
        class Student1234 {
          def each(): Unit = {
            println("我会吃饭")
          }
        }
        
        class Teacher1234 {
          def each(): Unit = {
            println("我会吃饭")
          }
        
          def teach(): Unit = {
            println("我会教书")
          }
        }
      2. 隐式转换定义在伴生对象中

        package com.lyz.scala.five
        
        object ImplicitLearn {
        
          def main(args: Array[String]): Unit = {
            /**
              * 编译器查找隐式转换的顺序
              *
              * 1.首先在源类型中或者目标类型中的伴生对象中查找是否有隐式转换函数
              * 2.在当前作用域中查找隐式转换
              * 3.利用import导入隐式转换
              */
            val student1234  = new Student1234
            student1234.teach()//增强的功能  
          } 
        }
        class Student1234 {
          def each(): Unit = {
            println("我会吃饭")
          }
        }
        
        class Teacher1234 {
          def each(): Unit = {
            println("我会吃饭")
          }
        
          def teach(): Unit = {
            println("我会教书")
          }
        }
        
        //Student1234类的伴生对象,里边定义了一个隐式转换函数
        object Student1234{
          //通过隐式转换增强了Studen1234这个类的功能
          implicit def stu2tea(student1234: Student1234): Teacher1234 ={
            new Teacher1234()
          }
        }
      3. 在父类中查找隐式转换

        package com.lyz.scala.five
        
        object ImplicitLearn {
        
          def main(args: Array[String]): Unit = {
        
            /**
              * 编译器查找隐式转换的顺序
              *
              * 1.首先在源类型中或者目标类型中的伴生对象或者父类的伴生对象中查找是否有隐式转换函数
              * 2.在当前作用域中查找隐式转换
              * 3.利用import导入隐式转换
              */
            val student1234  = new Student1234
            student1234.teach()//增强的功能
          } 
        }
        
        class Person1234
        
        //Person1234的伴生对象,子类也会在该对象中查找隐式转换
        object Person1234{
          implicit def stu2tea(student1234: Student1234): Teacher1234 ={
            new Teacher1234()
          }
        }
        
        class Student1234 extends Person1234{
          def each(): Unit = {
            println("我会吃饭")
          }
        }
        
        class Teacher1234 {
          def each(): Unit = {
            println("我会吃饭")
          }
        
          def teach(): Unit = {
            println("我会教书")
          }
        }

猜你喜欢

转载自blog.csdn.net/suubyy/article/details/80742136