3

我正在尝试使用 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 => Ordered[X] 的隐式转换存在的语法糖,并且以某种方式依赖于另一个清单的清单会导致问题。但是,我不知道到底发生了什么,或者更重要的是,不知道如何解决它。这在 Scala 中是否可能,如果没有,人们如何实现类似的东西?

4

2 回答 2

7

newInstance仅在T具有无参数构造函数时才有效。foo没有。视图绑定<%(就像上下文绑定一样:)是构造函数中隐式参数的快捷方式。

class foo[X <% Ordered[X]]是一样的class foo(implicit freshName: X => Ordered[X])foo缺少,的无参数构造函数newInstance失败。

于 2012-05-11T07:38:11.173 回答
5

You could make it work the following way:

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]]
}
于 2012-05-11T09:09:12.667 回答