是否可以从通用案例 class 创建编解码器提供程序?
Is it possible to create a Codec Provider from a generic case class?
我正在尝试创建一个通用函数,它从给定的通用案例 class 中生成 CodecProvider
。
BSON macro documentation没有给出任何例子。
This (unanswered) SO question 类似,但是我对为给定类型参数枚举所有可能的编解码器不感兴趣。另外,我的问题不涉及类型界限或类型差异。
这是一个无法编译的最小代码示例。
import org.mongodb.scala.bson.codecs.Macros
case class Foo(x: Int)
case class Bar[T](x: T)
def fooCodecProvider = Macros.createCodecProvider[Foo]()
// Compiles! (No generic)
def barCodecProvider[T] = Macros.createCodecProvider[Bar[T]]()
// Compile Error:(8, 70) class Bar takes type parameters
我希望 barCodecProvider
能够编译,但它没有。
上面的代码抛出的编译错误是class Bar takes type parameters
,这很让人困惑,因为我已经通过泛型[=13]的签名明确地将类型参数T
提供给了Bar
=] 函数。我有打字相关的语法错误吗?错误是否表示我使用 mongo-scala-driver 不正确?
虽然可以通过隐式查找与 circe 等其他库一起使用。
org.mongodb.scala.bson.codecs.Macros
似乎是不可能的,因为没有 Macro
函数接受参数。
但是如果你知道如何制作 Codec
,你可以自己动手做。
编解码器似乎是一个简单的特征,有 3 个方法 encode
decode
和 getEncoderClass
implicit val fooCodec : Codec[Foo] = Macros.createCodecProvider[Foo]()
def barCodecProvider[T: ClassTag](implicit codecT : Codec[T]) = new Codec[Bar[T]] {
override def decode(reader: BsonReader, decoderContext: DecoderContext): Bar[T] = {
Bar[T](codecT.decode(reader,decoderContext))
}
override def encode(writer: BsonWriter, value: Bar[T], encoderContext: EncoderContext): Unit = {
codecT.encode(writer, value.x, encoderContext)
}
//the tricky one
override def getEncoderClass: Class[Bar[T]] = classTag[Bar[T]].runtimeClass.asInstanceOf[Class[Bar[T]]]
}
val barFooCodec : Codec[Bar[Foo]] = barCodecProvider[Foo]
这是一个简单的示例,但它让您了解了可以做什么。
使用宏生成简单的实例,并将这些实例与使用隐含函数的函数组合起来,以自动获取正确的实例。
我正在尝试创建一个通用函数,它从给定的通用案例 class 中生成 CodecProvider
。
BSON macro documentation没有给出任何例子。
This (unanswered) SO question 类似,但是我对为给定类型参数枚举所有可能的编解码器不感兴趣。另外,我的问题不涉及类型界限或类型差异。
这是一个无法编译的最小代码示例。
import org.mongodb.scala.bson.codecs.Macros
case class Foo(x: Int)
case class Bar[T](x: T)
def fooCodecProvider = Macros.createCodecProvider[Foo]()
// Compiles! (No generic)
def barCodecProvider[T] = Macros.createCodecProvider[Bar[T]]()
// Compile Error:(8, 70) class Bar takes type parameters
我希望 barCodecProvider
能够编译,但它没有。
上面的代码抛出的编译错误是class Bar takes type parameters
,这很让人困惑,因为我已经通过泛型[=13]的签名明确地将类型参数T
提供给了Bar
=] 函数。我有打字相关的语法错误吗?错误是否表示我使用 mongo-scala-driver 不正确?
虽然可以通过隐式查找与 circe 等其他库一起使用。
org.mongodb.scala.bson.codecs.Macros
似乎是不可能的,因为没有 Macro
函数接受参数。
但是如果你知道如何制作 Codec
,你可以自己动手做。
编解码器似乎是一个简单的特征,有 3 个方法 encode
decode
和 getEncoderClass
implicit val fooCodec : Codec[Foo] = Macros.createCodecProvider[Foo]()
def barCodecProvider[T: ClassTag](implicit codecT : Codec[T]) = new Codec[Bar[T]] {
override def decode(reader: BsonReader, decoderContext: DecoderContext): Bar[T] = {
Bar[T](codecT.decode(reader,decoderContext))
}
override def encode(writer: BsonWriter, value: Bar[T], encoderContext: EncoderContext): Unit = {
codecT.encode(writer, value.x, encoderContext)
}
//the tricky one
override def getEncoderClass: Class[Bar[T]] = classTag[Bar[T]].runtimeClass.asInstanceOf[Class[Bar[T]]]
}
val barFooCodec : Codec[Bar[Foo]] = barCodecProvider[Foo]
这是一个简单的示例,但它让您了解了可以做什么。 使用宏生成简单的实例,并将这些实例与使用隐含函数的函数组合起来,以自动获取正确的实例。