暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

每日一课:类型投影

Scala学习 2016-02-28
203

什么是类型投影?类型投影有什么作用?先从内部类开始说起


Scala内部类同其成员变量一样,不同的对象实例对应的内部类是不同的,见下列代码:



scala> class Outter{

  val x:Int=0

  class Inner

}

defined class Outter

 

scala> val o1=new Outter

val o2=new Outter

o1: Outter = Outter@1ebe901

o2: Outter = Outter@7c1e7

 

scala> import scala.reflect.runtime.universe.typeOf

import scala.reflect.runtime.universe.typeOf

 

//o1.Innero2.Inner为不同的类型

scala> typeOf[o1.Inner]==typeOf[o2.Inner]

res0: Boolean = false



代码中定义了一个类class Outter,然后在该类中定义了一个内部类class Inner,代码val o1=new Outterval o2=new Outter定义了两个Outter对象,通过代码typeOf[o1.Inner]==typeOf[o2.Inner]可以看到o1.Innero2.Inner类型不相同。这种类型不相同在使用内部类时会产生一些问题,例如


/**

  * 类型投影

  */

object Example10_13 extends App{

   class Outter{

     val x:Int=0

     //定义Outter的成员方法test,方法参数为内部类Inner

     def test(i:Inner)=i

     class Inner

   }

 

   val o1=new Outter

   val o2=new Outter

 

   val inner2=new o2.Inner

   val inner1=new o1.Inner

 

   //编译通过

   o1.test(inner1)

 

   //编译出错

   //Error:(107, 12) typemismatch;

   //  found  : cn.scala.chapter10.Example10_13.o2.Inner

   //  required:cn.scala.chapter10.Example10_13.o1.Inner

   //  o1.test(inner2)

   //         ^

   o1.test(inner2)

}



Outter类中定义了接受内部类作为成员方法test的参数,代码o1.test(inner1)能够编译通过但o1.test(inner2)会编译报错,提示类型不匹配,其本质原因是o2.Innero1.Inner类型不同。在讲内部类的时候提到过,内部类同成员域、成员方法并没有区别除了它是一个类外。同成员域x一样,对象o1.x与对象o2.x本质上是不同的变量,它们在内存中的存储区域不同,而对o1.Innero2.Inner内部类也是一样的,它们本质上是不同的类。

 

要使方法def test(i:Inner)=i可以同时接受o1.Innero2.Inner类型的对象,可以将方法定义为def test(i:Outter#Inner)=I,函数参数中的Outter#Inner称为类型投影,其作用是将o1.Innero2.Inner两种不同的类型投影为Outter#Inner的子类,从而使得def test(i:Outter#Inner)方法可以接受o1.Innero2.Inner两种类型的对象,整体代码如下:


/**

  * 类型投影

  */

object Example10_13 extends App{

 

   class Outter{

     val x:Int=0

     deftest(i:Outter#Inner)=i

     class Inner

   }

 

   val o1=new Outter

   val o2=new Outter

 

   val inner2=new o2.Inner

   val inner1=new o1.Inner

 

   //编译通过

   o1.test(inner1)

   //编译通过

   o1.test(inner2)

}





文章转载自Scala学习,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论