【问题标题】:def'ine a value with a dynamic name用动态名称定义一个值
【发布时间】:2013-03-25 23:30:12
【问题描述】:

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

例如,我正在尝试这样做:

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

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

【问题讨论】:

  • 使用动态名称(在大多数语言/场景中)通常是 错误 方法.. 以后如何[统一] 访问这样的值?请参阅Clojure Data Structures 中的“地图”了解替代方案。
  • (术语“变量”通常与 PHP 相关联,但与这里询问的内容有关。)

标签: function clojure variable-variables


【解决方案1】:

首先,我必须指出,这似乎是个坏主意。为什么要尝试使用动态生成的名称生成 defs? (正如@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}

【讨论】:

  • 嘿,我想做的是创建多个具有不同名称的代理。我想创建 6 个类型为“服务器”的代理,因此每个代理都有名称: server0 。 .服务器5
  • @FengHuo - 如果你只想生成一堆“服务器”变量,为什么不把它们放在一个向量中呢?我会用一个例子来更新我的答案。
【解决方案2】:

def 的运行时等价物是intern

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

【讨论】:

    猜你喜欢
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 2013-02-16
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多