探讨Scala中的this.type

    在scala.collection.mutable.Builder中,有一个函数是这样的: def += (elem: Elem): Builder.this.type. 注意,+=的返回值是Builder.this.type,这个this.type是什么意思呢? 它和this有什么不一样?安全

    this.type表示当前对象(this)的类型this指代当前的对象。this.type被用于变量,函数参数和函数返回值的类型声明ide

    光说有点抽象,作几个实验函数

    代码片断一:     ui

trait IC{
    def me : this.type = this
    def entity: IC = this
}

class A extends IC
class B extends IC

val a = new A
:type a.me  // 显示A
:type a.entity //显示 IC
val b = new B  
:type a.me  // 显示 B
:type a.entity // 显示 IC

     代码片断二:     this

trait ActiveRecord {def entity: this.type = this} 

class Person extends ActiveRecord{
    override def entity = new ActiveRecord(){}  //编译错误,只能返回当前对象,即this
}

     代码片断三:.net

     代码片断四:scala

       简单解释一下。咱们平时这么写 val a = new A ,咱们会说a的类型是A。实际上,在编译这行代码时,编译器会自动生成一个类A的匿名子类(咱们不妨把它称为A_$) ,而后用这个匿名子类(A_$)实例化(而且只会实例化)一个对象(a)。咱们把这个匿名子类称为single class, 所以对象a的真正类型应该是这个A_$的类型,咱们把它叫作singe type。      code

      那this.type有什么做用呢? 主要是在某些场合下增强类型约束,或者说是为了确保类型的绝对安全。  以代码片断二为例,假如ActiveRecord的entity方法返回ActiveRecord类型, 那么实现类能够返回任意ActiveRecord类型的子类型。 所以将类型声明为this.type,能够对链式调用提供安全保障。 但这在Java中是没法作到的,除非把该方法声明为final,防止被子类改写,但这样一来就失去了灵活性。Play! 的ScaleModel类便运用了Scala的这种特性。 对象

       另外要说明的是,this.type是路径依赖的。请看下面的例子:blog

       

 

关于路径依赖类型的知识,请看http://my.oschina.net/aiguozhe/blog/35964?catalog=115675

 

参考资料:

 http://stackoverflow.com/questions/3926047/debunking-scala-myths/4339557#4339557