2011-07-29 108 views
6

我正在尋找一種方法來定義返回類型T的方法,其中T =子類的類型。斯卡拉抽象類型代表類型的子類

我知道我可以使用抽象類型來做到這一點,但不喜歡爲每個子類重新定義T的開銷。

一些示例代碼:

object Helper { 
    def help[A <: MyClass](cls: A): Option[A] = { cls.foo() map { _.asInstanceOf[A] } } 
} 

class MyClass { 
    type T <: MyClass 
    def foo(): Option[T] = Some(this.asInstanceOf[T]) 
} 

class ChildClass extends MyClass { 
    type T = ChildClass 
} 

可能是一個新的語言功能,使這更容易?或者我可以用某種方式使用this.type?對我來說,能夠定義一個可以以這種方式調用foo的助手類對我很重要。

回答

3

如果你總是返回this,那麼你的確可以有返回類型this.type。或者你已經嘗試過了嗎?

this.type是特別有用的,例如,當你想把調用鏈接到同一個對象時,或者提供一個靜態的保證,你將會返回同一個對象(而不是一個副本)。例如,Scala中的Buffer有附加操作:+,它返回Buffer[A]+=,返回this.type。前者重複可變序列;後者保證您更新原始對象。

+1

任何機會你可以指向一些特定的語法,因爲我需要完全按照(使用類型參數)編寫Helper.help? this.type不匹配A?另外,請注意我需要返回Option [this.type],並且def foo:Option [this.type] =有些(this)似乎沒有編譯。謝謝你的幫助! –

+1

@Pandora Singleton類型永遠不會被推斷出來,你必須明確地指定它:'Some [this.type](this)'。 –

+0

非常感謝!我遇到了另一個小故障,因爲我的foo函數實際上調用另一個對象的靜態方法 - >如果您有洞察力,請在這裏跟進問題:) http://stackoverflow.com/questions/6886182/scala-this- type-conformance-to-type-parameter-bounds-super-type –

2

要跟進讓 - 菲利普的答案,誰寫他什麼時候我在寫我的,下面的代碼:

trait SomeTrait { 
    def foo: this.type = this 
} 

class UsesTrait extends SomeTrait 

object Main { 
    def main(args: Array[String]) { 
    println((new UsesTrait).foo) // prints [email protected]<hash value> 
    } 
} 
+0

很酷,這很有幫助。這是否延伸到Option [this.type]? def foo:Option [this.type] =有些(this)似乎沒有編譯。 –

+0

嘿,我最終也是這樣結束了。這是考慮其重要性的最重要的語言特徵之一...... – lisak

2

我發現下面的成語有用:

class MyClass[T] { 
    self: T => 
    def foo(): Option[T] = Some(this) 
} 

class ChildClass extends MyClass[ChildClass] 

new ChildClass().foo() 
//--> Option[ChildClass] = Some([email protected]) 
+0

是的,但是:•如果要允許整個層次的類,它必須是一個特徵,並且•它必須是「 T'。總體而言,比簡單的'this.type'更多的約束,不是? –

+0

@ Jean-Philippe Pellet:是的,看起來像。我正在冥想它是否也有優勢,但沒有找到。 – Landei