[英]Could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[T]
It seems I don't understand something important, maybe about erasure (damn it). 似乎我不明白一些重要的事情,也许是关于擦除(该死的)。
I have a method, which I wanted to create array of size n
filled with values from gen
: 我有一个方法,我想创建一个大小为
n
数组,其中包含来自gen
值:
def testArray[T](n: Int, gen: =>T) {
val arr = Array.fill(n)(gen)
...
}
And use it, for example as: 并使用它,例如:
testArray(10, util.Random.nextInt(10))
But I get error: 但我得到错误:
scala: could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[T]
val arr = Array.fill(n)(gen)
^
Please, explain what I did wrong, why this error, and what kind of code it makes impossible? 请解释一下我做错了什么,为什么会出现这个错误,以及它使哪种代码变得不可能?
That is because in testArray
the concrete type of T
is not known at compile time. 这是因为在
testArray
,在编译时不知道具体的T
类型。 Your signature has to look like def testArray[T : ClassManifest](n: Int, gen: =>T)
, this will add an implicit parameter of type ClassManifest[T]
to your method, that is automatically passed to the call of testArray
and then further passed to the Array.fill
call. 你的签名必须看起来像
def testArray[T : ClassManifest](n: Int, gen: =>T)
,这会在你的方法中添加一个类型为ClassManifest[T]
的隐式参数,它会自动传递给testArray
的调用然后进一步传递给Array.fill
调用。 This is called a context bound
. 这称为
context bound
。
The Array.fill
method has the following signature: Array.fill
方法具有以下签名:
def fill[T](n: Int)(elem: => T)(implicit arg0: ClassManifest[T]): Array[T]
In order to get an instance of ClassManifest[T]
you need to know the concrete type. 为了获得
ClassManifest[T]
的实例,您需要知道具体类型。 A ClassManifest
can be obtained like this: ClassManifest
可以像这样获得:
implicitly[ClassManifest[String]]
A ClassManifest
is implicitly available for every concrete type. ClassManifest
隐式可用于每种具体类型。
For any implicit
error, you can add the implicits you require to the method with the type parameter: 对于任何
implicit
错误,您可以使用type参数向方法添加所需的隐含:
def wrap[T](n:Int)(elem: => T)(implicit c:ClassManifest[T], o:Ordering[T])
If you did not yourself introduce ClassManifest
or Ordering
, the writers of the library have (most likely) provided sensible defaults for you. 如果您没有自己介绍
ClassManifest
或Ordering
,那么库的编写者(很可能)会为您提供合理的默认值。
If you would call the wrap
method: 如果你要调用
wrap
方法:
wrap(2)(3)
It's expanded like this: 它像这样扩展:
wrap[Int](2)(3)(implicitly[ClassManifest[Int]], implicitly[Ordering[Int]])
If you introduced a custom class Person
here, you would get an error for not finding an implicit instance of Ordering[Person]
. 如果您在此处引入了自定义类
Person
,则会因为找不到Ordering[Person]
的隐式实例而收到错误。 The writers of the library could not have known how to order Person
. 图书馆的作者不知道如何订购
Person
。 You could solve that like this: 你可以解决这个问题:
class Person
implicit val o = new Ordering[Person] { // implement required methods }
wrap(2)(new Person)
The Scala compiler looks in different scopes for implicits, an Ordering
would usually not be specified like this. Scala编译器在不同的范围内查找implicits,通常不会像这样指定
Ordering
。 I suggest you look up implicit resolution on the internet to learn more about it. 我建议你在互联网上查找隐式解决方案,以了解更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.