Не удалось найти неявное значение для параметра доказательства типа scala.reflect.ClassManifest [T] - программирование
Подтвердить что ты не робот

Не удалось найти неявное значение для параметра доказательства типа scala.reflect.ClassManifest [T]

Кажется, я не понимаю что-то важное, возможно, об стирании (черт возьми).

У меня есть метод, который я хотел создать массив размера 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)
                       ^

Пожалуйста, объясните, что я сделал неправильно, почему эта ошибка и какой код это делает невозможным?

4b9b3361

Ответ 1

Это потому, что в testArray конкретный тип T не известен во время компиляции. Ваша подпись должна выглядеть как def testArray[T : ClassManifest](n: Int, gen: =>T), это добавит к вашему методу неявный параметр типа ClassManifest[T], который автоматически передается вызову testArray, а затем передается далее на вызов Array.fill. Это называется context bound.

Ответ 2

Метод Array.fill имеет следующую подпись:

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

Чтобы получить экземпляр ClassManifest[T], вам нужно знать конкретный тип. A ClassManifest можно получить следующим образом:

implicitly[ClassManifest[String]]

A ClassManifest неявно доступен для каждого конкретного типа.

Для любой ошибки 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 выглядит в разных областях для implicits, Ordering обычно не указывается так. Я предлагаю вам найти неявное разрешение в Интернете, чтобы узнать больше об этом.