(我看到了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))] ...)
答案 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]
的最后一点重复,我认为你必须使用一个宏。