在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