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 value
That is because in testArray
the concrete type of T
is not known at compile time. 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. This is called a context bound
.
The Array.fill
method has the following signature:
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. A ClassManifest
can be obtained like this:
implicitly[ClassManifest[String]]
A ClassManifest
is implicitly available for every concrete type.
For any implicit
error, you can add the implicits you require to the method with the type parameter:
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.
If you would call the wrap
method:
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]
. The writers of the library could not have known how to order 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. I suggest you look up implicit resolution on the internet to learn more about it.