Scala AggregateByKey在抽象类中时无法编译

Scala AggregateByKey在抽象类中时无法编译,scala,apache-spark,compiler-errors,abstract-class,Scala,Apache Spark,Compiler Errors,Abstract Class,我对Scala和Spark都是新手,所以我希望有人能解释为什么aggregateByKey在抽象类中无法编译。这是我能想到的最简单的例子: import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.rdd.RDD abstract class AbstractKeyCounter[K] { def keyValPairs(): RDD[(K, String)] def processData(

我对Scala和Spark都是新手,所以我希望有人能解释为什么aggregateByKey在抽象类中无法编译。这是我能想到的最简单的例子:

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

abstract class AbstractKeyCounter[K] {

  def keyValPairs(): RDD[(K, String)]

  def processData(): RDD[(K, Int)] = {
    keyValPairs().aggregateByKey(0)(
      (count, key) => count + 1,
      (count1, count2) => count1 + count2
    )
  }

}

class StringKeyCounter extends AbstractKeyCounter[String] {

  override def keyValPairs(): RDD[(String, String)] = {
    val sc = new SparkContext(new SparkConf().setMaster("local").setAppName("counter"))
    val data = sc.parallelize(Array("foo=A", "foo=A", "foo=A", "foo=B", "bar=C", "bar=D", "bar=D"))
    data.map(_.split("=")).map(v => (v(0), v(1)))
  }

}
其中:

Error:(11, 19) value aggregateByKey is not a member of org.apache.spark.rdd.RDD[(K, String)]
    keyValPairs().aggregateByKey(0)(
                  ^
如果我改为使用单个具体类,它将编译并成功运行:

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

class StringKeyCounter {

  def processData(): RDD[(String, Int)] = {
    val sc = new SparkContext(new SparkConf().setMaster("local").setAppName("counter"))
    val data = sc.parallelize(Array("foo=A", "foo=A", "foo=A", "foo=B", "bar=C", "bar=D", "bar=D"))
    val keyValPairs = data.map(_.split("=")).map(v => (v(0), v(1)))

    keyValPairs.aggregateByKey(0)(
      (count, key) => count + 1,
      (count1, count2) => count1 + count2
    )
  }

}
我缺少什么?

如果您更改:

abstract class AbstractKeyCounter[K] {
致:

这将编译

为什么
aggregateByKey
PairRDDFunctions
的一种方法(您的
RDD
被隐式转换为该类),它具有以下签名:

class PairRDDFunctions[K, V](self: RDD[(K, V)])
  (implicit kt: ClassTag[K], vt: ClassTag[V], ord: Ordering[K] = null)
这意味着它的构造函数需要类型为
ClassTag[K]
vt:ClassTag[V]
的隐式值。您的抽象类不知道K是什么,因此无法提供匹配的隐式值。这意味着到
pairddfunctions
的隐式转换“失败”(编译器不执行转换),因此无法找到方法
aggregateByKey

添加
[K:ClassTag]
是将隐式参数
隐式kt:ClassTag[K]
添加到抽象类构造函数的缩写,然后编译器使用它并将其传递给
pairrdfunctions
的构造函数

有关类标记及其优点的更多信息,请参见

class PairRDDFunctions[K, V](self: RDD[(K, V)])
  (implicit kt: ClassTag[K], vt: ClassTag[V], ord: Ordering[K] = null)