1

以下代码对我来说失败了:

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 文档并返回适当案例类的实例?

4

1 回答 1

2

1)宏应用程序在遇到时会立即扩展(嗯,模一些与此处无关的类型推断的精细细节)。这意味着当您编写 handler[T] 时,handler 将尝试以 T 作为类型参数进行扩展。这不会带来任何好处,因此会出现错误。为了使这个工作,你需要把 Message.parse 变成一个宏本身。

2) 发生这种情况是因为 ReactiveMongo 宏不卫生。具体来说,https://github.com/ReactiveMongo/ReactiveMongo/blob/v0.10.0/macros/src/main/scala/macros.scala#L142在像您这样的情况下无法正常工作,因为它使用简单的名称类的名称,而不是完全限定的名称。我认为使宏正常工作的最佳方法是使用 Ident(companion),而不是 Ident(companion.name) - 这将确保此标识符绑定到同伴,而不是范围内具有相同名称的东西。

于 2014-02-24T09:40:39.160 回答