3

所以我想将一个函数传递给 def 的“名称”部分。问题是:“def 的第一个参数必须是符号”

我正在尝试例如:

(def serverNumber 5)
(def (str "server" serverNumber) {:id serverNumber :value 4939})

但我找不到 annannnnny 方法来做到这一点。任何帮助将不胜感激:)

4

2 回答 2

3

首先,我必须指出,这似乎是个坏主意。您为什么要尝试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}
于 2013-03-25T23:42:23.137 回答
1

的运行时等价物defintern

(intern *ns*
        (symbol (str "server" server-number))
        {:id server-number :value 4939})
于 2013-03-26T19:49:58.397 回答