scala Scala将类型参数传递给对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2593487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scala passing type parameters to object
提问by Shahzad Mian
In Scala v 2.7.7
在 Scala v 2.7.7 中
I have a file with
我有一个文件
class Something[T] extends Other
object Something extends OtherConstructor[Something]
This throws the error:
这会引发错误:
class Something takes type parameters
object Something extends OtherConstructor[Something] {
类东西接受类型参数
对象东西扩展其他构造函数[东西] {
However, I can't do this
但是,我不能这样做
object Something[T] extends OtherConstructor[Something[T]]
It throws an error:
它抛出一个错误:
error: ';' expected but '[' found.
错误: ';' 预期但找到“[”。
Is it possible to send type parameters to object? Or should I change and simply use Otherconstructor
是否可以将类型参数发送到对象?或者我应该改变并简单地使用Otherconstructor
回答by oxbow_lakes
You could use:
你可以使用:
object Something extends OtherConstructor[Something[_]]
You will of course be restricted by having an existential typewith no upper bound in place instead of a concrete type. This solution may not make sense and you might need one object per concrete type T, for those T's which you care about, e.g.
您当然会受到没有上限的存在类型而不是具体类型的限制。此解决方案可能没有意义T,对于您关心的那些 T ,您可能需要每个具体类型一个对象,例如
object StringSomething extends OtherConstructor[Something[String]]
But then this has the (possible) disadvantage that StringSomethingis not the companion object of Something.
但是这有一个(可能的)缺点,StringSomething即不是Something.
However, my advice would be don't start messing about designing generic APIs(especially self-referential ones like the above) unless you really, reallyknow what you are doing. It will almost certainly end in tears and there are plenty of CORE Java API's which are terrible because of the way generics have been added (the RowSorterAPI on JTablebeing one example)
然而,我的建议是不要开始搞乱设计通用 API(尤其是像上面这样的自我引用的API),除非你真的、真的知道你在做什么。它几乎肯定会以泪水结束,并且有很多 CORE Java API 很糟糕,因为添加了泛型的方式(RowSorterAPIJTable就是一个例子)
回答by Thomas Jung
An object has to have a concrete type. The Scala object contruct is not a exception to this rule.
一个对象必须有一个具体的类型。Scala 对象结构也不例外。
A valid definition is
一个有效的定义是
object Something extends OtherConstructor[Something[T]] { }
where Tis some concrete type.
哪里T有一些具体的类型。
回答by Scott Smith
You can solve the general problem of needing object Foo[T]by moving the type parameter to the methods in object Foo:
您可以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)
}
If you really need one object per T, you can make a class, and have the type-free companion return it from apply.
如果你真的每个 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
}
Note this will re-construct the Foo[T] companion on each call so you would want to keep it light and stateless.
请注意,这将在每次调用时重新构建 Foo[T] 同伴,因此您希望保持轻量级和无状态。
An explicit solution the the problem above:
上述问题的显式解决方案:
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
}
回答by SiM
Thanks for the answers
感谢您的回答
object Something extends OtherConstructor[Something[_]]
seems to be compiling (although I have yet to run/test that :-))
似乎正在编译(虽然我还没有运行/测试:-))
@oxbow_lakes, I've followed your advice - of avoiding the type system - till now but I've got to do it!!! I've been studying existential types, type-erasure and all that but its still not in my grasp :-(
@oxbow_lakes,我已经听从了你的建议——避免使用类型系统——直到现在,但我必须这样做!!!我一直在研究存在类型、类型擦除和所有这些,但它仍然不在我的掌握中:-(

