定义具有动态名称的值

def'ine a value with a dynamic name

提问人:Riveascore 提问时间:3/26/2013 最后编辑:Riveascore 更新时间:3/27/2013 访问量:64

问:

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

例如,我正在尝试做:

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

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

函数 clojure variable-variables

评论

2赞 3/26/2013
使用动态名称(在大多数语言/场景中)通常是错误的方法。以后如何[统一]访问这样的值?有关替代方法,请参阅 Clojure Data Structures 中的“Maps”。
0赞 3/26/2013
(术语“变量”通常与 PHP 相关,但它与此处的问题有关。

答:

3赞 DaoWen 3/26/2013 #1

首先,我必须指出,这似乎是一个坏主意。为什么要尝试使用动态生成的名称生成 s?(正如@pst已经指出的那样,映射是创建具有动态生成标识符的绑定的常用解决方案。def

假设你有一个合法的理由这样做(也许它是你为用户生成 defs 的某些库功能的一部分),你可以用一个宏来实现这一点:

(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}

评论

0赞 Riveascore 3/26/2013
嘿,我想做的是创建多个具有不同名称的代理。我想创建 6 个类型为“server”的代理,因此每个代理都有名称:server0 。.服务器5
1赞 DaoWen 3/26/2013
@FengHuo - 如果你只想生成一堆“服务器”变量,为什么不把它们放在一个向量中呢?我将用一个例子来更新我的答案。
1赞 Matthias Benkard 3/27/2013 #2

运行时等效值为:defintern

(intern *ns*
        (symbol (str "server" server-number))
        {:id server-number :value 4939})