About Scala generics: cannot find class manifest for element type T

孤街浪徒 提交于 2020-01-23 05:37:05

问题


For a function as below:

def reverse[T](a: Array[T]): Array[T] = {
    val b = new Array[T](a.length)
    for (i <- 0 until a.length)
        b(i) = a(a.length -i - 1)
    b
}

I am getting "error: cannot find class manifest for element type T" from line 2.

Is there anyway to solve this?


回答1:


Simply add a context bound ClassManifest to your method declaration:

def reverse[T : ClassManifest](a: Array[T]): Array[T] = ...

In order to construct an array, the array's concrete type must be known at compile time. This type is supplied by the compiler via an implicit ClassManifest parameter. That is, the signature of the Array constructor is actually

Array[T](size: Int)(implicit m: ClassManifest[T]): Array[T]

In order to supply this parameter, there must be a ClassManifest in scope when the Array constructor is invoked. Therefore, your reverse method must also take an implicit ClassManifest parameter:

def reverse[T](a: Array[T])(implicit m: ClassManifest[T]): Array[T] = ...
// or equivalently
def reverse[T : ClassManifest](a: Array[T]): Array[T] = ...

The latter, simpler notation is called a context bound.




回答2:


When using [T : ClassManifest] if it is shown as deprecated use [T : ClassTag]




回答3:


While declaring Generic Type parameter, following ways works:

  • (T: ClassManifest), but it is shown deprecated in scala 2.11.
  • (T: Manifest)
  • (T: ClassTag), works without error, and looks like a perfect solution as the error given by compiler was:

    cannot find class tag for element type T

package com.github.sandip.adt

import scala.reflect.ClassTag

class QueueUsingArray[T](capacity: Int) {
  var array = new Array[T](capacity)

  private var front = -1
  private var rare = -1

  def enqueue(data: T) = {
    array(rare + 1) = data
    rare += 1
  }

  def dequeue: T = {
    front += 1
    array(front)
  }

  def isEmpty() = {
    !nonEmpty
  }

  def nonEmpty: Boolean = {
    rare > front
  }

}

object Main {
  def main(args: Array[String]): Unit = {
    val queue = new QueueUsingArray[Int](10)
    queue.enqueue(10)
    queue.enqueue(20)
    while (queue.nonEmpty) {
      println(queue.dequeue)
    }
  }
}


来源:https://stackoverflow.com/questions/3474073/about-scala-generics-cannot-find-class-manifest-for-element-type-t

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!