我试图在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
}

稍后,我在特定的类中实现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()))

这是怎么回事我该如何解决?

如果我通过以下方式更改了该类的声明:
abstract class Generic[T <: Product](implicit c: ClassTag[T]) extends Serializable {..

它有效,但是我不明白为什么,以及为什么隐式需要它。

最佳答案

这是怎么回事我该如何解决?

发生的事情是执行链中的方法之一要求存在ClassTag[T]实例。尽管此处没有实现,但我假设这是KafkaUtils.createDirectStream方法,该方法在运行时需要T类型的信息。

这有效:

abstract class Generic[T <: Product](implicit c: ClassTag[T])

因为现在当您调用createDirectStream时,隐式在作用域内。也就是说,编译器是在编译时为您填充相关类标记的编译器,现在createDirectStream在使用范围内具有相关的隐式。

08-18 08:16