有没有办法动态指定scala中的类型
Is there any way to specify type in scala dynamically
我是 Spark、Scala 的新手,很抱歉提出愚蠢的问题。所以我有一些 tables:
table_a, table_b, ...
以及这些 table 对应类型的数量
case class classA(...), case class classB(...), ...
然后我需要编写一个方法来从这些 table 中读取数据并创建数据集:
def getDataFromSource: Dataset[classA] = {
val df: DataFrame = spark.sql("SELECT * FROM table_a")
df.as[classA]
}
其他 table 和类型也是如此。有什么方法可以避免例行代码——我的意思是每个 table 都有单独的功能,并且只用一个?例如:
def getDataFromSource[T: Encoder](table_name: String): Dataset[T] = {
val df: DataFrame = spark.sql(s"SELECT * FROM $table_name")
df.as[T]
}
然后创建对列表 (table_name, type_name):
val tableTypePairs = List(("table_a", classA), ("table_b", classB), ...)
然后使用foreach调用它:
tableTypePairs.foreach(tupl => getDataFromSource[what should I put here?](tupl._1))
提前致谢!
像这样的东西应该可以工作
def getDataFromSource[T](table_name: String, encoder: Encoder[T]): Dataset[T] =
spark.sql(s"SELECT * FROM $table_name").as(encoder)
val tableTypePairs = List(
"table_a" -> implicitly[Encoder[classA]],
"table_b" -> implicitly[Encoder[classB]]
)
tableTypePairs.foreach {
case (table, enc) =>
getDataFromSource(table, enc)
}
注意这是丢弃一个值的情况,有点代码味。由于 Encoder
是不变的,因此 tableTypePairs
不会有那种有用的类型,
之类的东西也不会
tableTypePairs.map {
case (table, enc) =>
getDataFromSource(table, enc)
}
一个选项是将 Class
传递给方法,这样就可以推断出泛型类型 T
:
def getDataFromSource[T: Encoder](table_name: String, clazz: Class[T]): Dataset[T] = {
val df: DataFrame = spark.sql(s"SELECT * FROM $table_name")
df.as[T]
}
tableTypePairs.foreach { case (table name, clazz) => getDataFromSource(tableName, clazz) }
但是我不确定在没有 .asInstanceOf
的情况下,您将如何利用这个 Dataset
列表。
我是 Spark、Scala 的新手,很抱歉提出愚蠢的问题。所以我有一些 tables:
table_a, table_b, ...
以及这些 table 对应类型的数量
case class classA(...), case class classB(...), ...
然后我需要编写一个方法来从这些 table 中读取数据并创建数据集:
def getDataFromSource: Dataset[classA] = {
val df: DataFrame = spark.sql("SELECT * FROM table_a")
df.as[classA]
}
其他 table 和类型也是如此。有什么方法可以避免例行代码——我的意思是每个 table 都有单独的功能,并且只用一个?例如:
def getDataFromSource[T: Encoder](table_name: String): Dataset[T] = {
val df: DataFrame = spark.sql(s"SELECT * FROM $table_name")
df.as[T]
}
然后创建对列表 (table_name, type_name):
val tableTypePairs = List(("table_a", classA), ("table_b", classB), ...)
然后使用foreach调用它:
tableTypePairs.foreach(tupl => getDataFromSource[what should I put here?](tupl._1))
提前致谢!
像这样的东西应该可以工作
def getDataFromSource[T](table_name: String, encoder: Encoder[T]): Dataset[T] =
spark.sql(s"SELECT * FROM $table_name").as(encoder)
val tableTypePairs = List(
"table_a" -> implicitly[Encoder[classA]],
"table_b" -> implicitly[Encoder[classB]]
)
tableTypePairs.foreach {
case (table, enc) =>
getDataFromSource(table, enc)
}
注意这是丢弃一个值的情况,有点代码味。由于 Encoder
是不变的,因此 tableTypePairs
不会有那种有用的类型,
tableTypePairs.map {
case (table, enc) =>
getDataFromSource(table, enc)
}
一个选项是将 Class
传递给方法,这样就可以推断出泛型类型 T
:
def getDataFromSource[T: Encoder](table_name: String, clazz: Class[T]): Dataset[T] = {
val df: DataFrame = spark.sql(s"SELECT * FROM $table_name")
df.as[T]
}
tableTypePairs.foreach { case (table name, clazz) => getDataFromSource(tableName, clazz) }
但是我不确定在没有 .asInstanceOf
的情况下,您将如何利用这个 Dataset
列表。