这是我的第一个问题,希望我能提供足够的细节。随意要求澄清。
考虑以下因素,其中有效:
implicit def optionBsonReader[T, U](implicit ev: BsonReader[T, U]) = new BsonReader[Option[T], Option[U]] {
def read(obj: Option[U]): Option[T] = {
obj match {
case Some(x) => Some(x.fromBson[T])
case None => None
}
}
}
这段代码将选项包装的BSON片段转换为另一个选项[T]。我认为同样适用于列表,但以下内容不能编译:
implicit def listBsonReader[T, DBObject](implicit ev: BsonReader[T, DBObject]) = new BsonReader[List[T], MongoCursor] {
def read(cur: MongoCursor): List[T] = {
cur.map(_.fromBson[T]).toList
}
}
我使用以下代码作为一般机制:
package object bson {
def bsonReader[A, B](implicit reader: BsonReader[A, B]) = reader
def bsonWriter[A, B](implicit writer: BsonWriter[A, B]) = writer
implicit def addWriter[A](any: A): WithWriter[A] = new WithWriter(any)
implicit def addReader[A](any: A): WithReader[A] = new WithReader(any)
}
package bson {
private[bson] class WithWriter[A](any: A) {
def toBson[B](implicit writer: BsonWriter[A, B]): B = writer.write(any)
}
private [bson] class WithReader[B](any: B) {
def fromBson[A](implicit reader: BsonReader[A, B]): A = reader.read(any)
}
}
编译器错误:
could not find implicit value for parameter reader: project.marshalling.bson.BsonReader[T,com.mongodb.casbah.Imports.DBObject] cur.map(_.fromBson[T]).toList
这让我觉得奇怪,因为看起来编译器试图在调用fromBson来提供类型之前评估T.这让我觉得特别奇怪,因为期权读者似乎没有这样的抱怨。我最近才开始认真地在Scala中编码,所以我确信我在这里遗漏了一些东西。
如果您需要更多信息,请告诉我们,希望您能提供帮助。
最佳,
德克
答案 0 :(得分:2)
在listBsonReader中,没有理由输入类型U.您的游标在DBObject上迭代,map需要DbObject => X
函数。我想你有类似
implicit def withFromBson[U](x: U) = new {
def fromBson[T](implicit ev : BsonReader[T,U]) : T = ...
}
在地图中,_
键入DBObject
,通常从BsonReader[T, DBObject]
查看。您在隐式范围内不提供任何内容,只提供BsonReader[T,U]
。只需删除U
,并将隐式参数设为BsonReader[T,DBObject]
即可。
编译器没有提前评估T
。它试图确保调用网站上的T
和U
可能是什么(在这种情况下,U
是问题),它将具有隐式BSonReader[T, DBObject]
它隐含范围内的需求。我想在一般环境中没有。您使用隐式参数承诺,您将在呼叫站点提供一个BsonReader[T,U]
。这不是它所需要的。如果参数不是隐式的(你必须在调用fromBson
时写入ev),你会遇到类似的错误。