2010-04-07 94 views
8

在斯卡拉v 2.7.7斯卡拉传递类型参数为对象

我有

class Something[T] extends Other 

object Something extends OtherConstructor[Something] 

此文件引发错误:

class Something takes type parameters
object Something extends OtherConstructor[Something] {

但是,我不能这样做这

object Something[T] extends OtherConstructor[Something[T]] 

它会抛出一个错误:

error: ';' expected but '[' found.

是否可以向对象发送类型参数?或者我应该更改并简单地使用Otherconstructor

回答

3

对象必须具有一个具体类型。 Scala对象构造不是这个规则的例外。

甲有效的定义是

object Something extends OtherConstructor[Something[T]] { } 

其中T是一些具体类型

4

你可以使用:

object Something extends OtherConstructor[Something[_]] 

当然,你应在的地方,而不是一个具体类型具有生存型无上限限制。这个解决方案可能没有意义,你可能需要一个对象,每个具体类型为T,对于那些你关心的T,

object StringSomething extends OtherConstructor[Something[String]] 

但随后这个具有(可能)缺点StringSomething不是Something同伴对象。

但是,我的建议是不要开始摆弄设计一般API(尤其是自我指涉的像上面的),除非你真的,真的知道你在做什么。几乎可以肯定将结束在流泪,并有大量的核心Java API的,因为这样的仿制药已添加的这是可怕的(上JTableRowSorter API就是一个例子)

+0

APT的API也不错:'名单<?扩展AnnotationMirror> \t getAnnotationMirrors()'(http://java.sun.com/javase/6/docs/api/javax/lang/model/element/Element.html#getAnnotationMirrors%28%29);-) – 2010-04-07 15:32:29

1

感谢您的答案

object Something extends OtherConstructor[Something[_]] 

似乎编译(虽然我还没有遇到/测试:-))

@oxbow_lakes,我已经按照你的建议 - 避免类型的系统 - 到目前为止,但我必须这样做! 我一直在研究存在的类型,类型擦除和所有,但它仍然不是在我的掌握:-(

1

可以解决需要object Foo[T]通过移动类型参数的方法object Foo的普遍问题:

class Foo[T](t1: T, t2: T) 

object Foo { 
    def apply[T](x: T): Foo[T] = new Foo(x, x) 
    def apply[T](x: T, y: T): Foo[T] = new Foo(x, y) 
} 

如果你真的需要元T一个对象,你可以做一个类,并且有游离型,同伴从申请返回。

class Foo[T](t1: T, t2: T) 

class FooCompanion[T] { 
    def apply(x: T): Foo[T] = new Foo(x, x) 
    def apply(x: T, y: T): Foo[T] = new Foo(x, y) 
} 

object Foo { 
    def apply[T] = new FooCompanion[T] 
} 

object demo extends App { 
    val x: Foo[Double] = Foo.apply.apply(1.23) // this is what is really happening 
    val y: Foo[Int] = Foo[Int](123)    // with the type both apply calls are automatic 
} 

注意这将重新构建富[T ]同伴每次打电话时都要保持轻松和无状态。

一个明确的解决上述问题:

class Other 

class OtherConstructor[O <: Other] { 
    def apply(o: O): O = o // constructor 1 in base class 
} 

class Something[T](value: T) extends Other 

class SomethingConstructor[T] extends OtherConstructor[Something[T]] { 
    def apply(o: T, s: String) = new Something[T](o) // constructor 2 in subclass 
} 

object Something { 
    def apply[T] = new SomethingConstructor[T] // the "constructor constructor" method 
} 

object demoX extends App { 
    val si = new Something(123) 
    val sd = new Something(1.23) 

    val si1: Something[Int] = Something[Int](si)     // OtherConstructor.apply 
    val sd1: Something[Double] = Something[Double](1.23, "hello") // SomethingConstructor[Double].apply 
}