首页 > 解决方案 > 将案例类传递给函数参数

问题描述

抱歉问了一个简单的问题。我想将案例类传递给函数参数,并且我想在函数内部进一步使用它。到目前为止,我已经尝试过TypeTagClassTag但由于某种原因,我无法正确使用它,或者可能是我没有看正确的地方。

用例与此类似:

case class infoData(colA:Int,colB:String)
case class someOtherData(col1:String,col2:String,col3:Int)

def readCsv[T:???](path:String,passedCaseClass:???): Dataset[???] = {
  sqlContext
    .read
    .option("header", "true")
    .csv(path)
    .as[passedCaseClass]
}

它将被称为这样的东西:

val infoDf = readCsv("/src/main/info.csv",infoData)
val otherDf = readCsv("/src/main/someOtherData.csv",someOtherData)

标签: scalaapache-sparkapache-spark-datasetcase-classclasstag

解决方案


有两点需要注意

  1. 类名应该在CamelCase,所以InfoData.
  2. 将类型绑定到 aDataSet后,它就不是 a 了DataFrameDataFrame是 aDataSet的通用名称Row

您需要的是确保您提供的类Encoder在当前范围内具有相应的隐式实例。

case class InfoData(colA: Int, colB: String)

EncoderInt原始类型( ,String等)的实例,case classes可以通过导入获得spark.implicits._

def readCsv[T](path: String)(implicit encoder: Encoder: T): Dataset[T] = {
  spark
    .read
    .option("header", "true")
    .csv(path)
    .as[T]
}

或者,您可以使用上下文绑定,

def readCsv[T: Encoder[T]](path: String): Dataset[T] = {
  spark
    .read
    .option("header", "true")
    .csv(path)
    .as[T]
}

现在,您可以按以下方式使用它,

val spark = ...

import spark.implicits._

def readCsv[T: Encoder[T]](path: String): Dataset[T] = {
  spark
    .read
    .option("header", "true")
    .csv(path)
    .as[T]
}

val infoDS = readCsv[InfoData]("/src/main/info.csv")

推荐阅读