Casbah Mongo 驱动程序 Mongo 集合 class 的更新函数的奇怪柯里化

Weird currying of Update function of MongoCollection class of Casbah Mongo driver

如您所知,casbah mongodb 驱动程序具有如下更新功能:

def update [A, B] (q: A, o: B)(implicit arg0: (A) ⇒ DBObject, arg1: (B) ⇒ DBObject) : WriteResult

我想我了解 scala 的柯里化概念。然而,据我所知,这个更新函数应该像这样使用:

collection.update(MongoDBObject(...), MongoDBObject(...))

这让我很困惑。因为我没有填写更新方法的第二个参数列表,所以我认为上面的表达式会 return 一个像 :

这样的函数
(implicit arg0: (A) ⇒ DBObject, arg1: (B) ⇒ DBObject) => WriteResult

然而事实并非如此。是因为第二个函数参数列表中参数的隐式定义吗?

Casbah 库订阅 "pimp my library" 模式。它扩展了官方 MongoDB Java 驱动程序并添加了隐式和其他功能,使在 scala 中使用 Java 驱动程序感觉 "native"。

update 方法如下所示:

  /**
   * Performs an update operation.
   * @param q search query for old object to update
   * @param o object with which to update <tt>q</tt>
   */
  def update[A, B](q: A, o: B, upsert: Boolean = false, multi: Boolean = false,concern: com.mongodb.WriteConcern = this.writeConcern
this.writeConcern)(implicit queryView: A => DBObject,
                            objView: B => DBObject,
                            encoder: DBEncoder = customEncoderFactory.map(_.create).orNull): WriteResult = {
    underlying.update(queryView(q), objView(o), upsert, multi, concern, encoder)
}

Java 驱动程序需要 DBObject 进行更新操作,但 Casbah 提供了一个 Scala 帮助器用于在 MongoDBObject 中创建 DBObject。为了在 Scala 类型和 Java 类型之间提供互操作,我们可以使用 implicit parameters

因为编译器会在编译时知道 A,所以它可以确定 type A => DBObject 的隐式定义是否在范围内。 Casbah 然后使用该方法 queryView(q)q 转换为 DBObject 并将其传递给底层更新。