在clojure中动态添加变量to let语句

时间:2016-03-28 17:23:17

标签: clojure

(我看到了this问题,但这是一个不同的问题)

我希望能够在let语句中动态创建变量,例如从列表中创建变量。所以要获得以下内容:

(let [a (my-fn :a)
      b (my-fn :b)
      c (my-fn :c)])
我可以做这样的事吗? (特别是没有宏?)

(let [ (map (fn [x] '(x (my-fn x)))
            [:a :b :c])]) ;;<- this code obviously doesn't work

编辑:我试图对这个问题保持一般性,但也许太多了。建议这是一个XY问题,我可能用一个糟糕的解决方案来解决我的真正问题,这就是我想要的:在重新构建可能有很多输入的表单,并减少一遍又一遍地写同样的事情的复杂性。例如:

(let [project-form (re-frame/subscribe [:project-form])
      id           (rand-int 10000)
      project-name (reaction (:project-name @project-form))
      social-acct  (reaction (:social-acct @project-form))
      contact      (reaction (:contact @project-form))
      description  (reaction (:description @project-form))] ...)

1 个答案:

答案 0 :(得分:1)

我认为这是不使用宏的最接近的:

(ns clj.core
  (:require [clojure.string :as str] )
  (:use tupelo.core))

(def data   { :a 1
              :b 2
              :c 3 } )

(let [ks      [:a :b :c]
      v2      (reduce (fn [result curr-key]
                        (update result curr-key inc))
                      data
                      ks)
      _ (spyx v2)
      {:keys [:a :b :c]}    v2
    ; {:keys ks}            v2   <- this one won't work
]
  (spyx [a b c])
)

(defn -main [] )

;=> v2 => {:a 2, :b 3, :c 4}
;=> [a b c] => [2 3 4]

在尝试将数据转换为单独的符号之前,我们可以通过在原始地图上执行操作来避免部分麻烦。由于使用:keys进行解构是在编译时“设置”的,因此它不能使用向量ks,它通常可以在运行时更改。为了摆脱两次列出[:a :b :c]的最后一点重复,我认为你必须使用一个宏。