[英]Implicit class not working for Generic Type
我正在嘗試使用隱式類來簡化將數據加載到配置單元表中(使用 Spark)
例如說:如果這是我的數據,
case class Name(name: String, age: Int)
val lst = List(Name("name1", 24), Name("name2", 25))
我想像這樣將數據加載到表lst.loadToTable(db = "somedb", table = "sometable")
這是我到目前為止使用Implicit class
實現上述 ^ 所做的工作,
object TableHelper {
implicit class TableUtil[X: ClassTag](lst: Seq[X]){
def loadToTable(db: String, table: String)(implicit spark: SparkSession): Unit ={
println("Table -> " + table)
spark.catalog.tableExists(s"${db}.${table}") match {
case true =>
println(s"Table exist. Not creating new one: $table")
case false =>
println(s"Table DO NOT exist. Creating new one: $table")
// Create database
val ddl = s"CREATE DATABASE IF NOT EXISTS ${db}"
println("ddl -> " + ddl)
spark.sql(ddl)
// Create DataFrame
import spark.implicits._
val df = spark.sparkContext.parallelize(lst).toDF() // Compiler ERROR
// TODO: Pending: Create table & Load data
}
}
}
}
問題是,我收到此編譯器錯誤,
Error:(27, 66) value toDF is not a member of org.apache.spark.rdd.RDD[X]
val df = spark.sparkContext.parallelize(lst).toDF()
問題似乎是toDF()
在使用泛型類型時不起作用(在我的代碼中lst
是Seq[X]
)。 知道需要做什么來糾正這個問題嗎?
最后我能夠修復代碼(不知道為什么我的問題被否決了。如果指定原因會更有意義)。 感謝@Worakarn Isaratham 的指導。 與此處指定的內容相比,代碼需要進行一些額外的更改
import org.apache.spark.sql.SparkSession
import scala.reflect.ClassTag
import scala.reflect.runtime.universe._
object TableHelper {
// FIX is X <: Product : ClassTag : TypeTag
implicit class TableUtil[X <: Product : ClassTag : TypeTag](lst: Seq[X]){
def loadToTable(db: String, table: String)(implicit spark: SparkSession): Unit ={
println("Table -> " + table)
spark.catalog.tableExists(s"${db}.${table}") match {
case true =>
println(s"Table exist. Not creating new one: $table")
// TODO: Pending: Load data
case false =>
println(s"Table DO NOT exist. Creating new one: $table")
// Create database
val ddl = s"CREATE DATABASE IF NOT EXISTS ${db}"
println("ddl -> " + ddl)
spark.sql(ddl)
// Create DataFrame
import spark.implicits._
val df = spark.sparkContext.parallelize(lst).toDF()
df.show(100, false)
// TODO: Pending: Create table & Load data
}
}
}
}
[X <: Product : ClassTag : TypeTag]
成功了。 parallelize method
需要ClassTag
def parallelize[T: ClassTag](
seq: Seq[T],
numSlices: Int = defaultParallelism): RDD[T] = withScope {
X <: Product
可能告訴...我將要使用的通用類型實現了Product
特性(所有case class
實現了Product )
toDF方法需要toDF
才能訪問已擦除的類型(在運行時)
...現在我可以像這樣簡化調用約定
val lst = List(Name("name1", 24), Name("name2", 25))
lst.loadToTable("somedb", "sometable")
這是結果
+-----+---+
|name |age|
+-----+---+
|name1|24 |
|name2|25 |
+-----+---+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.