【问题标题】:Play-JSON cannot find implicit Writes[T] for type parameter TPlay-JSON 找不到类型参数 T 的隐式 Writes[T]
【发布时间】:2020-09-23 16:06:17
【问题描述】:

我是 Scala 新手,仍在学习大部分功能。 我正在尝试将 Dataset[T] 转换为 Json。 我正在使用 json play 来创建隐式写入。 加载数据集时,类型参数工作正常:

def processEvent[T](spark: SparkSession, inputPath: String)(implicit encoder: Encoder[T]): Unit = {
  val ds = spark.read.parquet(inputPath).as[T]
  ds.collect().foreach { event =>
    val serializedEvent = eventToJson[T](spark, event)
    postEvent(serializedEvent)
  }
}

但在调用EventToJson 时,我收到错误:No Json serializer found for type T. Try to implement an implicit Writes or Format for this type.

def eventToJson[T](spark: SparkSession, event: T): String = {
  Json.toJson(event).toString()
}

当我用我的案例类之一替换参数化类型时,代码可以正常工作:

def eventToJson(spark: SparkSession, event: MyCaseClass): String = {
  Json.toJson(event).toString()
}

为什么参数化类型找不到对应的case类和隐式Writes?

【问题讨论】:

标签: scala play-json


【解决方案1】:

尝试使用上下文绑定来约束 T

def eventToJson[T: Writes](spark: SparkSession, event: T): String = {
  Json.toJson(event).toString()
}

def eventToJson[T: Format](spark: SparkSession, event: T): String = {
  Json.toJson(event).toString()
}

那么您可能必须添加绑定到processEvent 的相同上下文

import org.apache.spark.sql.{Encoder, SparkSession}
import play.api.libs.json.{Json, Writes}

def processEvent[T: Encoder: Writes](spark: SparkSession, inputPath: String): Unit = {
  val ds = spark.read.parquet(inputPath).as[T]
  ds.collect().foreach { event =>
    val serializedEvent = eventToJson[T](spark, event)
    postEvent(serializedEvent)
  }
}

def eventToJson[T: Writes](spark: SparkSession, event: T): String = {
  Json.toJson(event).toString()
}

为什么参数化类型找不到对应的case类和隐式Writes?

因为它是为案例类定义的,而不是为T定义的(即使T可以成为应用eventToJson时的案例类类型)。

在 Scala 中,如果方法 foo 的定义产生编译错误,即找不到类型为 Bar 的隐式,那么您可以尝试将该隐式添加到 foo 的签名中

def foo(implicit bar: Bar) = ???

通过这种方式,您将隐式的解析推迟到调用foo 的时间。

如果类型是参数化的

def foo[T](implicit bar: Bar[T]) = ???

这可以用上下文绑定重写

def foo[T: Bar] = ???

Typeclasses methods called in functions with type parameters

How to resolve implicit lookup by bounded generic?

Implicit Encoder for TypedDataset and Type Bounds in Scala

【讨论】:

    猜你喜欢
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2016-09-22
    • 1970-01-01
    • 2020-08-19
    相关资源
    最近更新 更多