假设我们有一个表示文本的行数的类LineNumber:
class LineNumber ( val num : Int ) 
我们可以用这个类来表示一本书中每一页的行数:
val lineNumOfPage1 = new LineNumber(112)
val lineNumOfPage2 = new LineNumber(120)

上面的代码分别表示了第一页和第二页的行数。当然,我们也应该可以将它们相加,得到这两页的总行数:

val totalLineNum = lineNumOfPage1 + lineNumOfPage2
这样的话,我们的LineNumber类里就应该有一个 “+” 方法来将两个对象相加:
class LineNumber ( val num : Int ) {

  def + ( that : LineNumber ) = new LineNumber( this.num + that.num )

}

从直观上讲,我们甚至可以直接用整数来和LineNumber相加:

val totalLineNumber = lineNumOfPage1 + 

//或者

val totalLineNumber =  + lineNumOfPage2
写到这里我们发现,LineNumber对象中没有接受整型作为参数的 “+” 方法;而整型中也不会有接受LineNumber作为参数的 “+” 方法。
为了说明问题,我们不在LineNumber类中增加一个整型作为参数的重载方法,而是定义两个隐式转换,一个将Int转换为LineNumber,另一个将LineNumber转换为Int:
object LineNumber{

  implicit def intToLineNumber( i : Int ) = new LineNumber(i)

  implicit def lineNumberToInt( o : LineNumber ) = o.num

}

接下来再让我们尝试用LineNumber和整型相加:

import LineNumber._

val totalLineNumber1 = lineNumOfPage1 + 

val totalLineNumber2 =  + lineNumOfPage2
让我们看看在编译时加入 “-Xprint:typer” 后上面两句的结果:
val totalLineNumber1: LineNumber = lineNumOfPage1.+(LineNumber.intToLineNumber());

val totalLineNumber2: Int = .+(LineNumber.lineNumberToInt(lineNumOfPage2));

到这里已经很清楚了。Scala编译器优先选择了方法的参数作为转换对象,而没有选择调用方法的对象。这是为什么呢?其实,当程序类型检查出现问题的时候,Scala编译器会在两个位置上对出现问题的语句尝试使用隐式转换:

  • 第一个位置是 “可以直接将某个类型转换为期望的类型” 的地方
  • 第二个位置是 “可以将调用方法的对象转换为合适类型” 的地方

第一个位置是那种我们需要A但是传入的却是B的地方。上面的例子正好就是这样的情况,对于totalLineNumber1来说,lineNumOfPage1的 “+” 方法需要的参数类型是LineNumber型,然而我们传入的是Int类型,Scala编译器在这里检测到类型错误后,会寻找将Int转换为LineNumber的隐式转换。因为在代码开始时,我们利用 "import LineNumber._ " 导入了相应的隐式转换,因此Scala编译器使用导入的隐式转换将整型120转换为了LineNumber类型。totalLineNumber2发生的情况是相同的,只不过是将LineNumber类型转换为了Int类型。

       也就是说,Scala编译器在使用隐式转换的时候,首先回去寻找可以直接转换类型的位置,其次才对调用方法的对象。如果我们将我们的隐式转换中intToLineNumber的转换去掉,那么我们得到的totalLineNumber1就会变为一个整型。
 
转自:http://blog.csdn.net/nethibernate/article/details/5893184

Scala之隐式转换implicit详解的更多相关文章

  1. Scala 深入浅出实战经典 第62讲:Scala中上下文界定内幕中的隐式参数实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  2. Scala模式匹配| 隐式转换

    1. 模式匹配 Scala中的模式匹配类似于Java中的switch语法,但是更加强大.模式匹配语法中,采用match关键字声明,每个分支采用case关键字进行声明,当需要匹配时,会从第一个case分 ...

  3. scala自定义隐式转换

    Scala自定义隐式转换 一.编写隐式转换类 /** * Author Mr. Guo * Create 2019/4/20 - 17:40 */ object StringImprovments { ...

  4. Scala学习——隐式转换

    scala隐式转换 一.需求:为一个类添加一个新的方法 java:动态代理 scala:隐式转换 隐式转换例子: 1.man to superMan package top.ruandb.scala. ...

  5. 显示转换explicit和隐式转换implicit

    用户自定义的显示转换和隐式转换 显式转换implicit关键字告诉编译器,在源代码中不必做显示的转型就可以产生调用转换操作符方法的代码. 隐式转换implicit关键字告诉编译器只有当源代码中指定了显 ...

  6. 深入理解Scala的隐式转换系统

    摘要: 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码.   使用方式: 1. ...

  7. 转载:深入理解Scala的隐式转换系统

    摘要: 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码.   使用方式: 1. ...

  8. Scala之隐式转换

    概述 简单说,隐式转换就是:当Scala编译器进行类型匹配时,如果找不到合适的候选,那么隐式转化提供了另外一种途径来告诉编译器如何将当前的类型转换成预期类型. 隐式转换有四种常见的使用场景: 将某一类 ...

  9. Scala学习之路 (八)Scala的隐式转换和隐式参数

    一.概念 Scala 2.10引入了一种叫做隐式类的新特性.隐式类指的是用implicit关键字修饰的类.在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换. 隐式转换和隐式参数是Scal ...

随机推荐

  1. jQuery警告/确认/提示弹出对话框效果(替换传统JavaScript下的提示框)

    http://www.51xuediannao.com/js/jquery/jquery_tsk/ http://www.jq22.com/demo/jqueryConfirm20160413/

  2. js,javascript,打印对象,object

    function writeObj(obj){ var description = ""; for(var i in obj){ var property=obj[i]; desc ...

  3. Servlet Life Cycle

    Servlet Life Cycle http://docs.oracle.com/javaee/5/tutorial/doc/bnafi.html Servlet Filters and Event ...

  4. 安装BouncyCastle

    对于Windows而言 将bcprov-jdk16-146.jar 复制到C:\Program Files\Java\jre6\lib\ext和C:\jdk1.6.0\jre\lib\ext目录下: ...

  5. 2018-01-06自定义view时遇到的问题

    1.设置蒙版的简单写法: 2.

  6. 20145232 韩文浩 《Java程序设计》第5周学习总结

    教材学习内容总结 处理异常 教材中使用一个简单的程序,用户连续输入整数最后输入0结束后显示输入数的平均值. 但有时,用户会没有按常规出牌输入不正确的信息,例如"30"输成" ...

  7. 【python-字典】判断python字典中key是否存在的

    一般有两种通用做法: 第一种方法:使用自带函数实现: 在python的字典的属性方法里面有一个has_key()方法: #生成一个字典 d = {'name':Tom, 'age':10, 'Tel' ...

  8. The Seven Percent Solution

    Problem Description Uniform Resource Identifiers (or URIs) are strings like http://icpc.baylor.edu/i ...

  9. set_time_limit

    语法 : void set_time_limit (int seconds)说明 : 设定一个程式所允许执行的秒数,如果到达限制的时间,程式将会传回错误.它预设的限制时间是30秒,max_execut ...

  10. poj 3258 3273

    poj3258 题目  (最大化最小值)(最小值最大化) 题意:牛要到河对岸,在与河岸垂直的一条线上,河中有N块石头,给定河岸宽度L,以及每一块石头离牛所在河岸的距离,现在去掉M块石头,要求去掉M块石 ...