探討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

相關文章
相關標籤/搜索