scala - Circe:将隐式编码器移至通用类中

标签 scala generics types shapeless 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 ,我现在正在尝试一个可以将编码器构建到类中的示例。

但是当我运行上面的代码时,它说:

could not find implicit value for parameter encoder: 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)))
}

最佳答案

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?

答案是类 myClass 范围内没有可用的隐式 Encoder[T]

您可以通过将 (隐式编码器: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) 行运行时失败,因为您没有传入任何数据

how would I get the encoder that is defined implicitly into scope for the Class

构造函数是一个不错的选择

关于scala - Circe:将隐式编码器移至通用类中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62309073/

相关文章:

c# - 如何使 GlyphTypeface FontUri 通用

java - JAVA 中 HTML 页面的数据类型

c# - 将动态对象传递给 C# 方法会更改返回类型

Typescript:通过 'this' 获取自定义接口(interface)的类型?

c# - 比较类型是否可为空

scala - 按ID滑动选择行

java - Spark : Merging 2 columns of a DataSet into a single column

scala - 重载具有按名称调用参数的函数和具有按值参数的函数

scala - 使用不同选项的 akka 流物化值

generics - Kotlin 中的方差/协方差泛型