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)
    . . .

したがって、Xでパラメータ化された単純なクラスfooがあることがわかります。これは、Ordered[X]で囲まれたビューです。boo関数は、マニフェストを使用してfoo[String]の新しいインスタンスをインスタンス化しようとするだけです。ただし、この関数を呼び出すと、事態はひどく悪くなり、私が示したように開始するスタックトレースを取得します。fooのtypeパラメーターがビューバウンドでない場合、インスタンス化は問題なく機能します。これは、ビューバウンドがX => Ordered [X]の暗黙の変換の存在の単なる構文糖衣であり、マニフェストが別のマニフェストに依存していることが問題を引き起こしているという事実と関係があると思います。しかし、実際に何が起こっているのか、さらに重要なことに、それを修正する方法がわかりません。これはScalaでも可能ですか?そうでない場合、人々はどのようにして同様のことを達成しますか?

4

2 に答える 2

7

newInstanceTパラメータのないコンストラクタがある場合にのみ機能します。fooしていません。ビューバウンド<%(コンテキストバウンドと同じように:)は、コンストラクターの暗黙的なパラメーターのショートカットです。

class foo[X <% Ordered[X]]と同じclass foo(implicit freshName: X => Ordered[X])です。のパラメータなしコンストラクタがない場合foonewInstance失敗します。

于 2012-05-11T07:38:11.173 に答える
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]]
}
于 2012-05-11T09:09:12.667 に答える