在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