如何解决如何定义处理参数化类型数据集的方法?
我正在尝试定义一些函数,这些函数将 Dataset
s(类型化 DataFrame
s)作为输入并产生另一个作为输出,我希望它们足够灵活以处理参数化类型。在这个例子中,我需要一个列来表示用户的 ID,但如果该 ID 是 Int、Long、String 等,这对我的函数无关紧要。这就是为什么我的案例类有这个类型参数 {{ 1}}。
我起初尝试简单地编写我的函数并使用 A
而不是 Dataset
:
DataFrame
...但我收到此错误:
import org.apache.spark.sql.Dataset
case class InputT[A](id: A,data: Long)
case class OutputT[A](id: A,dataA: Long,dataB: Long)
def someFunction[A](ds: Dataset[InputT[A]]): Dataset[OutputT[A]] = {
ds.select().as[OutputT[A]] // suppose there are some transformations here
}
所以我尝试为我的类型提供一个编码器:
Unable to find encoder for type OutputT[A]. An implicit Encoder[OutputT[A]] is needed
to store OutputT[A] instances in a Dataset. Primitive types (Int,String,etc) and
Product types (case classes) are supported by importing spark.implicits._ Support
for serializing other types will be added in future releases.
现在我收到此错误:
import org.apache.spark.sql.Dataset
import org.apache.spark.sql.catalyst.encoders.ExpressionEncoder
case class InputT[A](id: A,dataB: Long)
implicit def enc[A]: Encoder[InputT[A]] = implicitly(ExpressionEncoder[OutputT[A]])
def someFunction[A](ds: Dataset[InputT[A]]): Dataset[OutputT[A]] = {
ds.select().as[OutputT[A]] // suppose there are some transformations here
}
如果代码与上面相同,但没有类型参数(例如,使用 No TypeTag available for OutputT[A]
而不是 String
),则没有错误。
尽可能避免使用 A
魔法,我应该怎么做才能解决这个问题?是否有可能通过 import spark.implicits._
实现这种级别的灵活性?
解决方法
如果您选中 Scaladoc,您会看到 as
需要一个 Encoder
,因此您只需要将其添加到范围。
def someFunction[A](ds: Dataset[InputT[A]])(implicit ev: Encoder[[OutputT[A]]): Dataset[OutputT[A]] = {
ds.select().as[OutputT[A]]
}
此外,您可能还想看看 Where does Scala look for implicits。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。