19

重要なこと、おそらく消去について理解していないようです(くそー)。

nからの値で満たされたサイズの配列を作成したいメソッドがありますgen

def testArray[T](n: Int, gen: =>T) {
  val arr = Array.fill(n)(gen)
  ...
}

たとえば、次のように使用します。

testArray(10, util.Random.nextInt(10))

しかし、私はエラーが発生します:

scala: could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[T]
val arr = Array.fill(n)(gen)
                       ^

私が何を間違えたのか、なぜこのエラーが発生したのか、どのようなコードが不可能になったのかを説明してください。

4

2 に答える 2

14

これはtestArray、具体的なタイプでTはコンパイル時に不明であるためです。シグニチャは次のようdef testArray[T : ClassManifest](n: Int, gen: =>T)になっている必要があります。これにより、タイプの暗黙的なパラメータがClassManifest[T]メソッドに追加されます。このパラメータは、の呼び出しに自動的に渡され、testArrayさらに呼び出しに渡されArray.fillます。これはと呼ばれcontext boundます。

于 2013-02-10T10:14:59.473 に答える
5

このArray.fillメソッドには次のシグネチャがあります。

def fill[T](n: Int)(elem: => T)(implicit arg0: ClassManifest[T]): Array[T]

インスタンスを取得するClassManifest[T]には、具体的なタイプを知る必要があります。Aは次のClassManifestように取得できます。

implicitly[ClassManifest[String]]

AClassManifestは、すべての具象タイプで暗黙的に使用できます。

エラーが発生した場合implicitは、typeパラメーターを使用して必要な暗黙をメソッドに追加できます。

def wrap[T](n:Int)(elem: => T)(implicit c:ClassManifest[T], o:Ordering[T])

ClassManifest自分で紹介したり、紹介したりしなかった場合Orderingは、ライブラリの作成者が(ほとんどの場合)賢明なデフォルトを提供しています。

メソッドを呼び出す場合wrap

wrap(2)(3)

これは次のように拡張されます。

wrap[Int](2)(3)(implicitly[ClassManifest[Int]], implicitly[Ordering[Int]])

ここでカスタムクラスを導入した場合Person、の暗黙のインスタンスが見つからないためにエラーが発生しますOrdering[Person]。ライブラリの作成者は、注文方法を知ることができませんでしたPerson。あなたはこのようにそれを解決することができます:

class Person

implicit val o = new Ordering[Person] { // implement required methods }

wrap(2)(new Person)

Scalaコンパイラーは、暗黙のスコープをさまざまに調べOrderingます。通常、このように指定することはありません。詳細については、インターネットで暗黙の解決策を調べることをお勧めします。

于 2013-02-10T12:19:10.997 に答える