【发布时间】:2017-04-24 20:17:18
【问题描述】:
我有一个 trait 用于注入 json 解码器作为我项目组件的依赖项:
trait JsonDecoder {
def apply[T](s: String): Option[T]
}
当我尝试使用Circe 实现它时:
import io.circe.generic.auto._
import io.circe.parser.decode
case class CirceJsonDecoder() extends JsonDecoder {
def apply[T](s: String): Option[T] = {
decode[T](s).fold(_ => None, s => Some(s))
}
}
然后运行:
case class C()
def test(d: JsonDecoder) = d[C]("{}")
test(CirceJsonDecoder())
它没有编译错误:
could not find implicit value for parameter decoder: io.circe.Decoder[T]
我尝试为T 添加ClassTag、TypeTag 或WeakTypeTag 上下文边界,但仍然找不到Decoder 的隐含值。
我无法将Decoder 上下文绑定或隐式参数添加到JsonDecoder.apply,因为使用它的组件不应该知道实现细节。
我应该如何提供隐式io.circe.Decoder?可能有什么方法可以从TypeTag获得它?
【问题讨论】:
-
据我了解,您尝试修复它的方式(通过
ClassTag/TypeTag添加反射),您假设 circe 使用反射来派生 json 编解码器。事实并非如此。相反,circe 在编译时派生编解码器,因此它需要的不仅仅是T关于类型的更多信息。您可以尝试shapeless.LabelledGeneric或shapless.Generic上下文绑定。