0

当我想测试结果是另一个函数的函数时发生。我有这样的事情:

ns flexsearch.core

(defn init [{:keys [tokenizer split indexer filter] :as options}]
  (let [encoder (get-encoder (:encoder options))]
    (assoc (merge {:ids {} :data {}} options)
           :indexer (get-indexer indexer)
           :encoder encoder
           :tokenizer (if (fn? tokenizer) tokenizer #(string/split % (or split #"\W+")))
           :filter (set (mapv encoder filter)))))

在测试中:

ns flexsearch.core-test
[flexsearch.core :as f]

(def split #"\W+")

(is (= (f/init {:tokenizer false :split split :indexer :forward :filter #{"and" "or"}})
         {:ids {},
          :data {},
          :tokenizer f/init/fn--14976,
          :split #"\W+",
          :indexer f/index-forward,
          :filter #{"or" "and"},
          :encoder f/encoder-icase}))

repl 中的结果是:

{:ids {},
 :data {},
 :tokenizer #function[flexsearch.core/init/fn--14976],
 :split #"\W+",
 :indexer #function[flexsearch.core/index-forward],
 :filter #{"or" "and"},
 :encoder #function[flexsearch.core/encoder-icase]}

我知道我必须放 f/index-forward 而不是 repl [flexsearch.core/index-forward] 的结果,但它不适用于 f/init/fn--14976 (No such var: f /init/fn--14976)

我认为这是 vars 的一个技巧,但我不知道它是如何工作的。你能提供的任何读物我将不胜感激

---编辑--- f/index-forward 和 f/encoder-icase 符号工作正常。

---编辑2---我已经定义:

(defn spliter [split]   (fn [x] (string/split x (or split #"\W+"))))

并将其用于:

(defn init [{:keys [tokenizer split indexer filter] :as options}]
  (let [encoder (get-encoder (:encoder options))]
    (assoc (merge {:ids {} :data {}} options)
           :indexer (get-indexer indexer)
           :encoder encoder
           :tokenizer (if (fn? tokenizer) tokenizer (spliter split))
           :filter (set (mapv encoder filter)))))

我得到了一个类似的“:tokenizer #function[flexsearch.core/spliter/fn--34857]”,我在测试中使用它,它也失败了——</p>

4

1 回答 1

0

认为“没有这样的 var”错误正在发生,因为标记器是一个匿名函数。

如果您将默认标记器定义为非匿名函数,flexsearch.core然后在测试中使用该名称,它将起作用。

但是,一般来说,您无法比较两个函数的相等性 - 正如@cfrick 所说。当您比较地图时,其中一些值是函数,您仍在比较函数。

于 2020-09-25T02:48:04.910 回答