2016-07-27 51 views
0

下面的代碼工作正常如果使用鏈方法時在繼承類

abstract class Base { 
    def append(value: Any): this.type = this 
} 

class Axis extends Base { 
    def text(value: String): this.type = append(value) 
} 

class XAxis extends Axis { 
    def position(value: Int): this.type = append(value) 
} 

def main(args: Array[String]): Unit = { 
    new XAxis().text("hello").position(0) 
} 

不指定this.type而如果我在Axis.text

class Axis extends Base { 
    // here we don't explicitly specify return type this.type 
    def text(value: String) = append(value) 
} 
刪除this.type爲什麼斯卡拉報告錯誤

斯卡拉報告

position不是Axis的成員。

的方法調用鏈

new XAxis().text將調用append

追加有返回類型this.type

thisXAxis一個實例。

所以this.typeAxis

因此無論指定this.type爲返回類型,斯卡拉應該總是可以推斷到真正的實例類型。

爲什麼它在我們明確指定返回類型this.type時有效?

但是,當我們沒有明確指定返回類型this.type時,它不起作用?

回答

2

當您不指定方法的返回類型時,編譯器會推斷它。更具體地說,編譯器總是會推斷出最精確的類型,但從來沒有單一類型(可以通過value.type表示法識別)。因此,在這種情況下,將推斷方法text以返回類型Axis,這是類別Axis中最精確的超類型this.type

+0

你的意思是說,當調用'text'時,編譯器知道它至少是Axis,但編譯器不會試圖推斷出真正的類型? –

+0

是的。但請注意,'this.type'永遠不會與「Axis」或「XAxis」「平等」。 'this.type'是一個單例類型,這意味着該類型的唯一實例是當前對象。在你的第一個例子中'this.type'將是'XAxis'的一個子類型,所以編譯器知道它有一個叫'position'的方法。 –

+0

Scala編譯器需要一些信息來推斷類型。對於'text'方法,唯一的信息是調用'append',它的返回類型是'this.type'。我們如何解釋'永遠不會推斷到單身類型'?因爲singleton類型是'text'可以得到的。 –