以下代码对我失败:
object Message {
def parse[T](bsonDoc: BSONDocument): Try[T] = {
implicit val bsonHandler = Macros.handler[T]
bsonDoc.seeAsTry[T]
}
}
Message.parse[messages.ClientHello](data)
错误是:
No apply function found for T
implicit val bsonHandler = Macros.handler[T]
^
但是,如果我对一个类型(我的一个案例类)进行硬编码,那很好:
object Message {
def parse(bsonDoc: BSONDocument): Try[ClientHello] = {
implicit val bsonHandler = Macros.handler[ClientHello]
bsonDoc.seeAsTry[ClientHello]
}
}
Message.parse(data)
所以我认为这是使用泛型的问题。顺便说一下,我必须import messages.ClientHello
。如果我只使用messages.ClientHello
,我会得到:
not found: value ClientHello
implicit val bsonHandler = Macros.handler[messages.ClientHello]
^
我如何实现我正在尝试做的事情,即使用单个方法获取BSON文档并返回相应案例类的实例?
答案 0 :(得分:2)
1)宏应用程序在遇到时会立即扩展(嗯,模拟一些与此类无关的类型推断的细节)。这意味着当您编写处理程序[T]时,处理程序将尝试使用T作为类型参数进行扩展。这不会导致任何好的,因此错误。要使其工作,您需要将Message.parse转换为宏本身。
2)这是因为ReactiveMongo宏是不卫生的。具体来说,https://github.com/ReactiveMongo/ReactiveMongo/blob/v0.10.0/macros/src/main/scala/macros.scala#L142在像你这样的情况下无法正常工作,因为它使用类的简单名称,而不是完全限定名。我认为使宏正常工作的最佳方法是使用Ident(伴侣),而不是Ident(companion.name) - 这将确保此标识符绑定到伴侣,而不是具有相同名称的范围内的东西。