Scala Spark toDF在导入sqlContext隐式后无法解析符号

Scala Spark toDF在导入sqlContext隐式后无法解析符号,scala,apache-spark,dataframe,apache-spark-sql,Scala,Apache Spark,Dataframe,Apache Spark Sql,我正在为Scala Spark应用程序编写一些单元测试 为此,我需要在测试中创建不同的数据帧。因此,我编写了一个非常简短的DFsBuilder代码,它基本上允许我添加新行并最终创建DF。代码是: class DFsBuilder[T](private val sqlContext: SQLContext, private val columnNames: Array[String]) { var rows = new ListBuffer[T]() def add(row: T): D

我正在为Scala Spark应用程序编写一些单元测试 为此,我需要在测试中创建不同的数据帧。因此,我编写了一个非常简短的DFsBuilder代码,它基本上允许我添加新行并最终创建DF。代码是:

class DFsBuilder[T](private val sqlContext: SQLContext, private val columnNames: Array[String]) {
  var rows = new ListBuffer[T]()

  def add(row: T): DFsBuilder[T] = {
    rows += row
    this
  }

  def build() : DataFrame = {
    import sqlContext.implicits._
    rows.toList.toDF(columnNames:_*) // UPDATE: added :_* because it was accidently removed in the original question
  }
}
但是,toDF方法不会使用无法解析符号toDF进行编译

我用泛型编写了这个构建器代码,因为我需要创建不同类型的DFs(不同的列数和不同的列类型)。我希望使用它的方式是在单元测试中定义一些特定的case类,并将其用于构建器

我知道这个问题在某种程度上与我使用泛型(可能是某种类型的类型擦除问题)这一事实有关,但我不太清楚到底是什么问题

所以我的问题是:

  • 有人能告诉我问题出在哪里吗?还有希望如何修复它
  • 如果这个问题不能用这种方法解决,有人能提供另一种优雅的方法来创建数据帧吗?(我不喜欢用创建代码污染我的单元测试)
很明显,我首先在谷歌上搜索了这个问题,但只找到了一些例子,其中人们忘记了导入sqlContext.implicits方法或关于超出范围的case类的内容,这可能与我遇到的问题不同


提前感谢

如果您查看
toDF
SQLImplicits.localSeqToDataFrameHolder
(使用的隐式函数)的签名,您将能够检测到两个问题:

  • 类型
    T
    必须是
    Product
    的子类(所有大小写类的超类,元组…),并且必须为其提供隐式
    TypeTag
    。要解决此问题,请将类的声明更改为:

    class DFsBuilder[T <: Product : TypeTag](...) { ... }
    

  • 通过这两个更改,您的代码可以编译(并工作)

    实际上,第二个项目中使用了列名,我可能不小心擦掉了它或其他什么。我为此道歉。扩展产品和类型标签确实有效!非常感谢:)只是添加了应该使用导入scala.reflect.runtime.universe.TypeTag导入TypeTag的用法:
    import-scala.reflect.runtime.universe.TypeTag
    ,因为Java显然也有一个TypeTag类
    rows.toList.toDF(columnNames: _*)