在环境(Clojure)中定义函数,然后在代码中使用它

在环境(Clojure)中定义函数,然后在代码中使用它,clojure,Clojure,我希望能够使用Environ在我的Lieningen项目中定义一个匿名函数 以下是项目文件的该部分的外观: {:env {:foo (fn [s] (count s))}} 然后在我的代码中,我想使用这个函数。比如: (-> "here are a few words" (env :foo)) (let [f (eval (env :foo))] (-> "here are a few words" f)) 然后要获得s的

我希望能够使用Environ在我的Lieningen项目中定义一个匿名函数

以下是项目文件的该部分的外观:

{:env {:foo (fn [s]
                (count s))}}
然后在我的代码中,我想使用这个函数。比如:

(-> "here are a few words"
    (env :foo))
(let [f (eval (env :foo))]
  (-> "here are a few words"
      f))

然后要获得
s

的大小,Environ只需在slurped文件上调用。
:foo
处的值将是一个包含符号
fn
的列表,后面是一个内部带有符号
s
的向量,依此类推。i、 e.表单尚未评估,因此您将无法调用匿名
fn

考虑这一点:

(def f (read-string "(fn [s] (count s))"))

(f "test")
;; => ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

(def evaled-f (eval (read-string "(fn [s] (count s))")))
(evaled-f "test")
;; => 4
此外,您的预期用途也有点偏离
->
是一个宏,它将获取第一个参数并将其“线程化”到以下形式的第一个位置

(macroexpand '(-> "here are a few words" (env :foo)))
;; => (env "here are a few words" :foo)
我想你在寻找类似的东西:

(-> "here are a few words"
    (env :foo))
(let [f (eval (env :foo))]
  (-> "here are a few words"
      f))
(env:foo)
返回列表。要从中生成函数,可以使用
eval
或更好的宏,如下所示:

(defmacro defn-env [fn-name env-key]
  `(def ~fn-name ~(env env-key)))

(defn-env env-fn :foo) ; => #'user/env-fn

(env-fn [1 2 3]) ; => 3

注意:如果
(env:foo)
返回
nil
,您需要将
:插件[[lein environ“1.0.0”]]
添加到您的
项目中。clj

感谢您的精彩解释,这正是我想要的!