scala - Circe:将隐式编码器移动到泛型类中
问题描述
我正在与 Circe 图书馆合作,并想学习其中的技巧。考虑以下代码:
import io.circe.generic.auto._
import io.circe.syntax._
import io.circe.{Decoder, Encoder, Json}
sealed trait Something
case class Name(val name: String) extends Something
class myClass[T](name: Option[Name] = None, data: Option[Seq[T]] = None) {
// convert an arbitrary sequence to json
def seqToJson[T](lst: Seq[T])(implicit encoder: Encoder[T]): Json = {
lst.asJson
}
val mydata: Json = seqToJson(data.get)
}
object Trace extends App {
val name = new myClass(Some(Name("Noob")))
}
继这里的优秀答案之后:Link,我现在正在尝试一个可以将编码器构建到类中的示例。
但是,当我运行上面的代码时,它说:
找不到参数编码器的隐含值:io.circe.Encoder[T] [error] val mydata: Json = seqToJson(data.get) [error] ^
现在我的问题是,为什么会发生这种情况。当我将隐式编码器的定义移动到类内部时,为什么编译器无法拾取如何使用它?
我也尝试了其他方法,即移动到我定义隐式编码器的位置:
import io.circe.generic.auto._
import io.circe.syntax._
import io.circe.{Decoder, Encoder, Json}
sealed trait Something
case class Name(val name: String) extends Something
class myClass[T](name: Option[Name] = None, data: Option[Seq[T]] = None)(implicit encoder: Encoder[T]) {
// convert an arbitrary sequence to json
def seqToJson[T](lst: Seq[T]): Json = {
lst.asJson
}
val mydata: Json = seqToJson(data.get)
}
object Trace extends App {
val name = new myClass(Some(Name("Noob")))
}
这给出了以下错误:
找不到参数编码器的隐含值:io.circe.Encoder[Seq[T]] 不明确的隐含值:
[error] both lazy value encodeDuration in object Encoder of type io.circe.Encoder[java.time.Duration]
[error] and lazy value encodeInstant in object Encoder of type io.circe.Encoder[java.time.Instant]
[error] match expected type io.circe.Encoder[T]
[error] Error occurred in an application involving default arguments.
[error] val name = new myClass(Some(Name("Noob")))
所以我的问题是,我如何将隐式定义的编码器纳入类的范围。任何解释该理论的答案将不胜感激!
编辑:使用伊万的结构,它的工作原理!
import io.circe.syntax._
import io.circe.{Decoder, Encoder, Json}
class myClass[T](data: Seq[T])(implicit encoder: Encoder[T]) {
def seqToJson(lst: Seq[T]): Json = {
lst.asJson
}
}
object Trace extends App {
println(new myClass[Int](data = Seq(1,2,3)))
}
解决方案
现在我的问题是,为什么会发生这种情况。当我将隐式编码器的定义移动到类内部时,为什么编译器无法拾取如何使用它?
Encoder[T]
答案是在 class 范围内没有隐式可用myClass
。
您可以通过移动(implicit encoder: Encoder[T])
到构造函数来修复它,您已经这样做了。
此外,您T
在两个地方定义泛型类型
class myClass[T]
和
def seqToJson[T]
你应该只保留一个myClass
找不到参数编码器的隐含值:io.circe.Encoder[Seq[T]] 不明确的隐含值:
这是由于缺少泛型类型的问题造成的。T
创建新实例时没有指定类型myClass
。如果你这样做,它将编译。
例如,
val name = new myClass[Int](Some(Name("Noob")))
这将在运行时在线失败,seqToJson(data.get)
因为您没有传入任何data
.
我如何将隐式定义的编码器纳入类的范围
构造函数是一个不错的选择