2011-09-16 36 views
3

解釋一個例子:在Scala中,如何在包含類之外爲嵌套類型創建工廠?

class A { 
    def f = { 
     val b: B = C.factory(this).asInstanceOf[B] 
    } 
    class B 
} 

object C { 
    def factory(a: A): A#B = new a.B 
} 

C.factory是創建A#B的新實例的功能。由於B是嵌套類型,因此我在函數簽名中包含了一個A引用。調用函數f必須投射從factory返回的引用,這是我想避免的。沒有演員我得到:

error: type mismatch; 
found : A#B 
required: A.this.B 

回答

7

這取決於你想要什麼。在A中,B表示this.B,即從封閉實例創建的B。事實上你的工廠會回報這一點,但它並沒有這樣說。它只是說它返回A#B(稱爲類型投影),某個未指定的A實例的B。如果你的val b不關心創建了哪個實例,那麼你應該用val b來表達:A#B(或者讓編譯器推斷它)。

如果你確實關心它是你的A而不是其他的,那麼你可能會倒黴。您的factory返回由a參數創建的B的實例。但是你的簽名並沒有這麼說。你會想要a.B,而不是較不精確的類型投影A#B。唉,該語言不允許。您將得到一個錯誤非法依賴方法類型:當您編寫依賴類型a.B時,a必須是「穩定標識符」,並且方法參數不被視爲一個。也許this blog post可能會幫助

+0

謝謝!是的,我想我的工廠函數返回a.B,但正如你所說,這不會編譯。 –

+2

您可以使用選項'-Ydependent-method-types'來啓用依賴方法類型,而無需其餘的實驗功能。這個功能沒有官方支持,但也許會改變。 –

相關問題