我正在尝试在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 {..
它有效,但我不明白为什么,为什么隐含的是必要的。
答案 0 :(得分:5)
发生了什么事?我怎么能解决它?
正在发生的事情是执行链中的一个方法需要存在ClassTag[T]
的实例。虽然我们这里没有实现,但我假设这是KafkaUtils.createDirectStream
方法,它在运行时需要类型为T
的信息。
这有效:
abstract class Generic[T <: Product](implicit c: ClassTag[T])
因为现在调用createDirectStream
时隐含在范围内。也就是说,编译器是在编译时为您填写相关类标记的编译器,现在createDirectStream
具有相关的隐含范围。