scala 隐式转换,隐式参数,隐式类

来源:互联网 发布:json xml yml yaml 编辑:程序博客网 时间:2024/05/30 02:22

Scala隐式转换

Scala的隐式转换是一个十分常用的功能这里我们将介绍怎么简单的使用隐式转换。

package data/**  * Created by LiuWenSheng on 2017/9/29.  */class MyInt(i:Int){  private val pro = i  def +(x:MyInt)= new MyInt(x.pro+this.pro)}object ImplicitDemo {  object MyImplicitTypeConversion {    implicit def intToMyInt(i:Int) = new MyInt(i)  }  def main(args: Array[String]) {    import ImplicitDemo.MyImplicitTypeConversion.intToMyInt    val c = 1+new MyInt(1)    println(c)  }}

这里我们自定义了一个类为MyInt类,该类有个一方法为+,所以对于任意的两个MyInt类对象都可以进行相加操作。但是请看main函数中的相加操作

val c = 1+new MyInt(1)

这个正如你所知道的1为int类型,而且int类型中并没有和MyInt类对象相加的方法。但是为什么这里可以使用相加的操作呢?
请看上一行代码!

import ImplicitDemo.MyImplicitTypeConversion.intToMyInt

这里导入了我们自定义的intToMyInt隐式转换方法,所以编译器在遇到int类型和MyInt类型相加的时候会自动地把Int类型按照我们定义的如下方式进行操作

implicit def intToMyInt(i:Int) = new MyInt(i)

也就是把Int类型转换为MyInt类型

隐式类

请先看实例代码

package data/**  * Created by LiuWenSheng on 2017/9/29.  */class MyInt(i:Int){  val pro = i  def +(x:MyInt)= new MyInt(x.pro+this.pro)}object mydefine{    implicit class ImplicitFun(val x:Int){      def IntToMyInt = {        println("隐式类被调用!")       new MyInt(x)      }    }}object ImplicitDemo {  def main(args: Array[String]) {    import mydefine._    val c = new MyInt(1) + 1.IntToMyInt    println(c)  }}

结果输出为

隐式类被调用!data.MyInt@2c8d66b2

这里我们定义了ImplicitFun隐式转换类,可以看到隐式转换类被调用了,这里和上一例有所不同的是
上一例相加时用的操作为

val c = 1+new MyInt(1)

但是本例中使用的相加操作为

val c = new MyInt(1) + 1.IntToMyInt

可以看出多了那么一点东西为IntToMyInt,而这个IntToMyInt正是我们之前定义的隐式类中的方法

    implicit class ImplicitFun(val x:Int){      def IntToMyInt = {        println("隐式类被调用!")       new MyInt(x)      }    }

可以看出def定义的隐式相比class定义的隐式来说隐藏的比较深(不容易看出),class定义的隐式会相对比较容易看出,1后面添加IntToMyInt方法也显得比较精确。

隐式参数

请看实例代码

package data/**  * Created by LiuWenSheng on 2017/9/29.  */class MyInt(i:Int){  val pro = i  def +(x:MyInt)(implicit  a:MyInt = new MyInt(1))= new MyInt(x.pro+this.pro+a.pro)}object ImplicitDemo {  def main(args: Array[String]) {    val c = new MyInt(1)+ new MyInt(1)    val d = new MyInt(1).+( new MyInt(1))(new MyInt(2))    println(c.pro)    println(d.pro)  }}

可以看出函数

  def +(x:MyInt)(implicit  a:MyInt = new MyInt(1))= new MyInt(x.pro+this.pro+a.pro)

注意该函数函数名的后面有两个括号其中最后一个括号为(implicit a:MyInt = new MyInt(1))这是什么意思呢?
如果传递了参数那么就按照传递的参数计算,如果没有传递参数那么就按照这个隐式的参数计算,所以结果正如你所料

34

第一个没有传递参数,所以按照隐式参数来,为1+1+1=3
第二个传递了参数所以按照传递的参数计算为1+1+2=4