【读书笔记】利用隐式转化丰富现有类库的功能

 

《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 ....

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

 

posted on 2015-10-18 14:57  develooop  阅读(275)  评论(0编辑  收藏  举报

导航

AmazingCounters.com