zoukankan      html  css  js  c++  java
  • 【读书笔记】利用隐式转化丰富现有类库的功能

    《scala for the impatient》 隐式转换和隐式参数

    所谓隐式转换(implicit conversion function)是以implicit声明的带有单个参数的函数。

    它会自动应用,将值从一个类型转到另一种类型。

    隐式转化函数可以是任何名称,不需要被显示调用。

    1.利用隐式转化丰富现有类库的功能

    在scala中可以基于原类型自定义一个经过装饰过丰富过的类型

    //为java.io.File 类增加一个read方法
    class RichFile(val from: java.io.File) {
      def read = Source.fromFile(from.getPath).mkString
    }
    

     

    然后提供一个隐式转化类将原来的类型转换到新类型

    implicit def file2RichFile(from: java.io.File) = new RichFile(from)
    

    测试

    package test.scala.lang.implicit_
    
    import scala.io.Source
    import test.scala.lang.implicit_.RichFile._
    
    //为java.io.File 类增加一个read方法
    class RichFile(val from: java.io.File) {
      def read = Source.fromFile(from.getPath).mkString
    }
    
    object RichFile{
       implicit def file2RichFile(from: java.io.File) = new RichFile(from)
    }
    
    object TestImplicit {
      
      def main(args: Array[String]): Unit = {
        test
      }
      
      def test = {
        val file = new java.io.File("src/main/resources/log4j.properties")
        println(file.read)
      }
    }
    

    2.引入隐式转换

    scala会考虑如下的隐式转换函数:

    • 位于原类型或目标类型的伴生对象中的隐式函数
    • 位于当前作用域可以以 单个标识符 指代的隐式函数

    比如上面的

    implicit def file2RichFile(from: java.io.File) = new RichFile(from)

    位于RichFile的伴生对象中。

    在import的时候

    不是import test.scala.lang.implicit_.RichFile,这样引入的是伴生对象本身,read方法不能 以单个标识符调用,需要带上类型名称,RichFile.read;

    在REPL中,可以通过:implicits 来查看所有除Predef外被引入的隐式成员.

    引入隐式转换的 尽量使用局部化的方式,也可以引入单个隐式转换

    import test.scala.lang.implicit_.RichFile.file2RichFile

    3.隐式转换规则

    隐式转换在以下三种情况下会被考虑

    • 当表达式的类型与预期的类型不同时
    • 当对象访问一个不存在的成员时
    • 当对象调用某个方法,而该方法的参数声明与传入参数不匹配时

    以下三种情况编译器不会尝试使用隐式转换:

    • 如果不使用隐式转换即可通过编译,则不使用隐式转换;
    • 编译器不会尝试同时执行多个隐式转换;
    • 存在二义性的转换是个错误,编译器将会报错;

    编译时使用参数

    scalac -Xprint:typer ....

    可以看到加入隐式转换后的代码。

  • 相关阅读:
    Hibernate系列教材 (五)- 基础
    Hibernate系列教材 (四)- 基础
    Hibernate系列教材 (三)- 基础
    Hibernate系列教材 (二)- 基础
    Hibernate系列教材 (一)- 基础
    Spring系列教材 (六)- 注解方式测试
    LDU20级新生排位赛第三场
    POJ3678——Katu Puzzle(2-SAT)
    进阶指南图论——闇の連鎖 I. 黑暗的锁链(树上差分+LCA)
    2021年度训练联盟热身训练赛第一场——Early Orders(单调栈)
  • 原文地址:https://www.cnblogs.com/ihongyan/p/4889533.html
Copyright © 2011-2022 走看看