所以我想将一个函数传递给 def 的“名称”部分。问题是:“def 的第一个参数必须是符号”
我正在尝试例如:
(def serverNumber 5)
(def (str "server" serverNumber) {:id serverNumber :value 4939})
但我找不到 annannnnny 方法来做到这一点。任何帮助将不胜感激:)
所以我想将一个函数传递给 def 的“名称”部分。问题是:“def 的第一个参数必须是符号”
我正在尝试例如:
(def serverNumber 5)
(def (str "server" serverNumber) {:id serverNumber :value 4939})
但我找不到 annannnnny 方法来做到这一点。任何帮助将不胜感激:)
首先,我必须指出,这似乎是个坏主意。您为什么要尝试def
使用动态生成的名称生成 s ?(正如@pst 已经指出的那样,映射是使用动态生成的标识符创建绑定的常用解决方案。)
假设您有这样做的正当理由(也许它是您为用户生成定义的某些库功能的一部分),您可以使用宏来完成此操作:
(defmacro def' [sym-exp & other-args]
`(def ~(-> sym-exp eval symbol) ~@other-args))
(def serverNumber 5)
(def' (str "server" serverNumber) {:id serverNumber :value 4939})
请注意,这只适用于顶层(因为宏在编译时运行)。如果你想在函数或其他东西中这样做,那么你只需要使用 eval:
(defn def'' [sym-exp & other-args]
(eval `(def ~(-> sym-exp eval symbol) ~@other-args)))
如果您只想创建一堆代理,也许这样的事情会起作用:
(def servers
(vec (for [i (range 5)]
{:id i :value 4939})))
然后你可以通过索引访问它们:
(servers 0)
; => {:id 0, :value 4939}
的运行时等价物def
是intern
:
(intern *ns*
(symbol (str "server" server-number))
{:id server-number :value 4939})