我正在尝试使用Scala的清单来实例化一个类型,当在带有视图绑定的类型上对该类型进行参数化时,我遇到了问题。我已将问题归结为以下代码:
class foo[X <% Ordered[X]]() {}
def boo[T](implicit m : Manifest[T]) = { m.erasure.newInstance().asInstanceOf[T] }
boo[foo[String]]
java.lang.InstantiationException: foo
at java.lang.Class.newInstance0(Class.java:357)
at java.lang.Class.newInstance(Class.java:325)
. . .
所以你可以看到我们有一个简单的类foo,它在X上参数化;这是由Ordered [X]限定的视图。 boo函数只是尝试使用清单来实例化foo [String]的新实例。然而,当调用这个函数时,事情会非常糟糕,我得到的堆栈跟踪就像我展示的那样开始。当foo的类型参数不是视图有界时,实例化工作没有问题。我认为这与以下事实有关:视图绑定只是存在X =&gt;的隐式转换的语法糖。订购[X],并且不知何故清单依赖于另一个清单导致问题。但是,我不知道发生了什么,或者更重要的是,如何解决它。这在Scala中是否可能,如果没有,人们如何实现类似的东西呢?
答案 0 :(得分:7)
newInstance
具有无参数构造函数时, T
才有效。 foo
没有。视图绑定<%
(就像上下文绑定:
)是构造函数中隐式参数的快捷方式。
class foo[X <% Ordered[X]]
与class foo(implicit freshName: X => Ordered[X])
相同。缺少foo
的无参数构造函数,newInstance
失败。
答案 1 :(得分:5)
您可以通过以下方式使其工作:
def boo[A, B[_]](implicit toOrdA: A => Ordered[A], mf: Manifest[B[A]]): B[A] = {
val constructor = mf.erasure.getConstructor(classOf[A => Ordered[A]])
constructor.newInstance(toOrdA).asInstanceOf[B[A]]
}