我正在为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进行编译。
我用泛型编写了这个构建器代码,因为我需要创建不同类型的DF(不同数量的列和不同的列类型)。我想用它的方法是在单元测试中定义一些特定的case类,并将它用于构建器
我知道这个问题在某种程度上与我使用泛型(可能是某种类型的擦除问题)的事实有关,但我无法完全理解问题是什么
所以我的问题是:
我显然首先搜索了这个问题,但只找到了人们忘记导入sqlContext.implicits方法的例子,或者是关于案例类的一些例子,这可能与我没有相同的问题
提前致谢
答案 0 :(得分:1)
如果您查看toDF
和SQLImplicits.localSeqToDataFrameHolder
的签名(这是使用的隐式函数),您将能够检测到两个问题:
类型T
必须是Product
的子类(所有案例类的超类,元组...),并且必须为它提供隐式TypeTag
。要解决此问题 - 将类的声明更改为:
class DFsBuilder[T <: Product : TypeTag](...) { ... }
columnNames
参数不是Array
类型,它是&#34;重复参数&#34; (比如Java&#34; varargs&#34;,请参阅第4.6.2节here),因此您必须将数组转换为参数:
rows.toList.toDF(columnNames: _*)
通过这两项更改,您的代码可以编译(并且可以正常工作)。