3

这是我在这里的第一个问题,所以希望我提供足够的细节。随时要求澄清。

考虑到以下几点,这是可行的:

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
    }
  }
}

这段代码将 Option 包装的 BSON 片段转换为另一个 Option[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 编写代码,所以我确信我在这里遗漏了一些东西。

如果您需要更多信息,请告诉我,希望您能提供帮助。

最好的,

短剑

4

1 回答 1

2

在您的 listBsonReader 中,没有理由输入 U。您的光标在 DBObject 上迭代,map 需要一个DbObject => X函数。我猜你有类似的东西

implicit def withFromBson[U](x: U) = new {
   def fromBson[T](implicit ev : BsonReader[T,U]) : T = ...
}

在 map 中,使用_typedDBObject时,通常是从BsonReader[T, DBObject]. 您在隐式范围内不提供任何内容,仅提供BsonReader[T,U]. 只需删除U并让您的隐式参数 be BsonReader[T,DBObject]

编译器不会尝试T提前评估。它试图确保调用站点上的任何内容TU在这种情况下,U就是问题所在),它将BSonReader[T, DBObject] 在隐式范围内具有所需的隐式。我想一般环境中没有。您用您的隐含参数承诺您将BsonReader[T,U]在呼叫现场提供一个。这不是它所需要的。如果参数不是隐式的(调用时您必须在 ev 处编写fromBson),您将遇到类似的错误。

于 2011-09-06T05:56:00.637 回答