Circe:将隐式编码器移动到通用 Class
Circe: Moving an Implicit Encoder into A Generic Class
我在 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")))
}
继这里的优秀答案之后:,我现在正在尝试一个示例,我可以在其中将编码器构建到 class。
但是当我运行上面的代码时,它说:
could not find implicit value for parameter encoder:
io.circe.Encoder[T] [error] val mydata: Json = seqToJson(data.get)
[error] ^
现在我的问题是,为什么会这样。当我将隐式编码器的定义移动到 class 中时,为什么编译器无法使用它?
我也尝试了其他方法,就是移动到我定义隐式编码器的地方:
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")))
所以我的问题是,如何将隐式定义的编码器获取到 Class 的范围内。任何对理论进行解释的答案将不胜感激!
编辑:使用 Ivan 的结构并且有效!
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)))
}
Now my question is, why is this happening. When I move the definition
of the implicit encoder inside the class, why can the compiler not
pick up how to use it?
答案是在classmyClass
的范围内没有隐含的Encoder[T]
可用。
您可以通过将 (implicit encoder: Encoder[T])
移动到构造函数来修复它,您这样做了。
此外,您在两个地方定义了通用类型 T
class myClass[T]
和
def seqToJson[T]
你应该只在 myClass
保留一个
could not find implicit value for parameter encoder:
io.circe.Encoder[Seq[T]] ambiguous implicit values:
这是由于缺少泛型类型的问题造成的。创建 myClass
的新实例时,您没有指定类型 T
。如果你这样做,它会编译。
例如,
val name = new myClass[Int](Some(Name("Noob")))
这将在运行时在线 seqToJson(data.get)
上失败,因为您没有传入任何 data
.
how would I get the encoder that is defined implicitly into scope for
the Class
构造函数是一个不错的选择
考虑以下简化的片段
def f[T](v: Option[T] = None) = v
f() // T is inferred as Nothing
这里类型参数T
被推断为Nothing
因为None
被定义为
case object None extends Option[Nothing]
于是出现以下情况
def f[T](v: Option[T] = None)(implicit ev: Encoder[T]) = v
f() // error because requiring Encoder[Nothing] capability
我们实际请求Encoder[Nothing]
有哪些错误。事实上,你可以通过简单地请求
来模拟类似的错误
implicitly[Encoder[Nothing]]
哪些错误
Error: diverging implicit expansion for type io.circe.Encoder[Nothing]
starting with lazy value encodeZoneOffset in object Encoder
不确定为什么它特别提到 encodeZoneOffset
,但这可能与隐式搜索的工作方式有关,而 encodeZoneOffset
是 Encoder
同伴中的 last 隐式值。
我在 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")))
}
继这里的优秀答案之后:
但是当我运行上面的代码时,它说:
could not find implicit value for parameter encoder: io.circe.Encoder[T] [error] val mydata: Json = seqToJson(data.get) [error] ^
现在我的问题是,为什么会这样。当我将隐式编码器的定义移动到 class 中时,为什么编译器无法使用它?
我也尝试了其他方法,就是移动到我定义隐式编码器的地方:
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")))
所以我的问题是,如何将隐式定义的编码器获取到 Class 的范围内。任何对理论进行解释的答案将不胜感激!
编辑:使用 Ivan 的结构并且有效!
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)))
}
Now my question is, why is this happening. When I move the definition of the implicit encoder inside the class, why can the compiler not pick up how to use it?
答案是在classmyClass
的范围内没有隐含的Encoder[T]
可用。
您可以通过将 (implicit encoder: Encoder[T])
移动到构造函数来修复它,您这样做了。
此外,您在两个地方定义了通用类型 T
class myClass[T]
和
def seqToJson[T]
你应该只在 myClass
could not find implicit value for parameter encoder: io.circe.Encoder[Seq[T]] ambiguous implicit values:
这是由于缺少泛型类型的问题造成的。创建 myClass
的新实例时,您没有指定类型 T
。如果你这样做,它会编译。
例如,
val name = new myClass[Int](Some(Name("Noob")))
这将在运行时在线 seqToJson(data.get)
上失败,因为您没有传入任何 data
.
how would I get the encoder that is defined implicitly into scope for the Class
构造函数是一个不错的选择
考虑以下简化的片段
def f[T](v: Option[T] = None) = v
f() // T is inferred as Nothing
这里类型参数T
被推断为Nothing
因为None
被定义为
case object None extends Option[Nothing]
于是出现以下情况
def f[T](v: Option[T] = None)(implicit ev: Encoder[T]) = v
f() // error because requiring Encoder[Nothing] capability
我们实际请求Encoder[Nothing]
有哪些错误。事实上,你可以通过简单地请求
implicitly[Encoder[Nothing]]
哪些错误
Error: diverging implicit expansion for type io.circe.Encoder[Nothing]
starting with lazy value encodeZoneOffset in object Encoder
不确定为什么它特别提到 encodeZoneOffset
,但这可能与隐式搜索的工作方式有关,而 encodeZoneOffset
是 Encoder
同伴中的 last 隐式值。