2011-07-29 86 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