简体   繁体   English

关于Scala泛型:找不到元素类型T的类清单

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

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. 我从第2行得到“错误:无法找到元素类型T的类清单”。

Is there anyway to solve this? 反正有没有解决这个问题?

Simply add a context bound ClassManifest to your method declaration: 只需在方法声明中添加一个上下文绑定的ClassManifest

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. 此类型由编译器通过隐式ClassManifest参数提供。 That is, the signature of the Array constructor is actually 也就是说,Array构造函数的签名实际上是

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. 为了提供此参数,在调用Array构造函数时,范围内必须有ClassManifest。 Therefore, your reverse method must also take an implicit ClassManifest parameter: 因此,您的反向方法还必须采用隐式ClassManifest参数:

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 . 后者,更简单的表示法称为上下文绑定

使用[T:ClassManifest]时如果显示为已弃用[T:ClassTag]

While declaring Generic Type parameter, following ways works: 在声明Generic Type参数时,以下方式有效:

  • (T: ClassManifest), but it is shown deprecated in scala 2.11. (T:ClassManifest),但在scala 2.11中显示已弃用。
  • (T: Manifest) (T:清单)
  • (T: ClassTag), works without error, and looks like a perfect solution as the error given by compiler was: (T:ClassTag),无误地工作,看起来像一个完美的解决方案,因为编译器给出的错误是:

    cannot find class tag for element type T 找不到元素类型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)
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM