2014-02-23 28 views
1

下面的代碼爲我失敗:麻煩與ReactiveMongo的BSON宏和仿製藥

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文檔,並且返回適當的情況下類的一個實例一個單一的方法?

+1

這個宏從哪裏來?我可以看看。 –

+0

https://github.com/ReactiveMongo/ReactiveMongo/tree/v0.10.0/macros/src/main/scala – Derecho

回答

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(companion),而不是Ident(companion.name) - 這將確保此標識符綁定到同伴,而不是與具有相同名稱的範圍內的東西綁定。