在 Clojure 中包装

Wrapping in Clojure

有时我无法在 Clojure 中包装函数或宏。

例如Clojure Mongo offers a DSL to query collections: with-collection,这是一个宏。

一种使用方法如下所示:

(with-collection db coll
    (find {})
    (sort (array-map :score -1 :name 1)))

我想创建一个接收排序函数并调用 with-collection 的函数。

(defn find [sort]
    (with-collection my-db my-coll
       (find {})
       sort
)

如果我尝试调用该函数,我会收到以下错误:ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

(find (sort (array-map :score -1 :name 1))

我猜这是因为正在评估 sort 而 with-collection 需要一个函数。

如果我尝试引用我得到以下错误:ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

(find (quote sort (array-map :score -1 :name 1)))

如果我尝试传递匿名函数,我会收到以下错误:ArityException 传递给的参数 (1) 数量错误:main/eval139628/fn--139629

(find #(sort (array-map :score -1 :name 1))

是否可以使用函数来包装这种宏?谢谢。

问题是 with-collection 宏扩展为 ->,因此您的函数应该将 coll 作为第一个参数。您还可以使用 `find 函数隐藏 monger find 函数。也许你应该这样做:

(defn my-find [sort]
  (with-collection my-db my-coll
    (find {})
    sort)

并这样称呼它:

(my-find #(sort % (array-map :score -1 :name 1))