通用Scala.没有ClassTag可用于T

Gui*_*lle 2 scala

我正在尝试在Scala中使用泛型,但在某些情况下它对我不起作用.

我已经将类定义为:

trait Generic[T <: Product] extends Serializable {

   def start(ssc: StreamingContext, conf: Conf) = {
    val dstream = createDirectStream(...)
    val rdd = dstream.map(x => avroToObject(x.value()))
    execute(rdd)
   }

   def execute(dstreamAvro: DStream[T]): Unit
   def avroToObject(bytes: Array[Byte]): T
}
Run Code Online (Sandbox Code Playgroud)

后来,我在特定的类中实现了avroToObject方法.当我尝试编译代码时,我收到一个错误.

Error:(36, 30) No ClassTag available for T
    val rddAvro = dstream.map(x => avroToObject(x.value()))
Error:(36, 30) not enough arguments for method map: (implicit evidence$2: scala.reflect.ClassTag[T])org.apache.spark.streaming.dstream.DStream[T].
Unspecified value parameter evidence$2.
    val rddAvro = dstream.map(x => avroToObject(x.value()))
Run Code Online (Sandbox Code Playgroud)

它发生了什么?我该怎么办呢?

如果我通过以下方式更改了类的声明:

abstract class Generic[T <: Product](implicit c: ClassTag[T]) extends Serializable {..
Run Code Online (Sandbox Code Playgroud)

它有效,但我不明白为什么,以及为什么隐含它是必要的.

Yuv*_*kov 5

它发生了什么?我该怎么办呢?

发生的事情是执行链中的一个方法需要一个实例ClassTag[T]存在.虽然我们这里没有实现,但我假设这是在运行时KafkaUtils.createDirectStream需要类型信息的方法T.

这有效:

abstract class Generic[T <: Product](implicit c: ClassTag[T])
Run Code Online (Sandbox Code Playgroud)

因为现在调用时隐含在范围内createDirectStream.也就是说,编译器是在编译时为您填写相关类标记的编译器,现在createDirectStream具有相关的隐含使用范围.