在Scala v 2.7.7中
我有一个带
的文件class Something[T] extends Other
object Something extends OtherConstructor[Something]
这会引发错误:
class Something采用类型参数
object Something extends OtherConstructor [Something] {
但是,我不能这样做
object Something[T] extends OtherConstructor[Something[T]]
抛出错误:
错误:';'预期,但'''发现。
是否可以将类型参数发送给对象?或者我应该改变并简单地使用Otherconstructor
答案 0 :(得分:4)
您可以使用:
object Something extends OtherConstructor[Something[_]]
您当然会受到限制,因为存在类型没有上限而不是具体类型。这个解决方案可能没有意义,每个具体类型T
可能需要一个对象,对于那些你关心的T,例如。
object StringSomething extends OtherConstructor[Something[String]]
但是这有(可能)的缺点,StringSomething
不是Something
的伴侣对象。
然而,我的建议是不要开始搞乱设计通用API (特别是上面提到的自我引用的),除非你真的,真的知道你是什么是做。它几乎肯定会流泪,因为添加了泛型的方式(RowSorter
上的JTable
API就是一个例子),有很多CORE Java API很糟糕。
答案 1 :(得分:3)
对象必须具有具体类型。 Scala对象构造不是此规则的例外。
有效的定义是
object Something extends OtherConstructor[Something[T]] { }
其中T
是具体类型。
答案 2 :(得分:2)
您可以通过将type参数移动到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一个对象,你可以创建一个类,并让无类型的伴侣从apply中返回它。
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
}
请注意,这将在每次调用时重新构建Foo [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
}
答案 3 :(得分:1)
感谢答案
object Something extends OtherConstructor[Something[_]]
似乎正在编译(虽然我还没有运行/测试: - ))
@oxbow_lakes,我遵循了你的建议 - 避免使用类型系统 - 直到现在,但我必须这样做! 我一直在研究存在主义类型,类型擦除等等但它仍然不在我的掌握之中: - (