2013-03-25 4 views
3

Итак, я хочу передать функцию в раздел «имя» def. Проблема заключается в том: «Первый аргумент опр должен быть символ»def'ine значение с динамическим именем

Я пытаюсь сделать, например:

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

Но я не могу найти annnnnnny способ сделать это. Любая помощь была бы недооценена :)

+2

Использование динамических имен (в большинстве языков/сценариев) часто является * неправильно * подход .. как бы такое значение [равномерно] доступ позже? См. «Карты» в [Структуры данных Clojure] (http://clojure.org/data_structures) для альтернативы. – 2013-03-25 23:39:06

+0

(Термин «переменные переменные» обычно связан с PHP, но он связан с тем, что здесь задают.) – 2013-03-25 23:45:10

ответ

3

Во-первых, я должен отметить, что это кажется плохой идеей. Почему вы пытаетесь сгенерировать def с динамически сгенерированными именами? (Как уже указывалось @pst, карты являются обычным решением для создания привязок с динамически генерируемыми идентификаторами.)

Предполагая, что у вас есть законная причина для этого (возможно, это часть некоторых библиотечных функций, в которых вы создаете defs для пользователя), вы можете сделать это с помощью макроса:

(defmacro def' [sym-exp & other-args] 
    `(def ~(-> sym-exp eval symbol) [email protected])) 

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

Обратите внимание, что это работает только на верхнем уровне (так как макросы выполняются во время компиляции). Если вы хотите сделать это в функции или что-то, то вам просто нужно использовать Eval:

(defn def'' [sym-exp & other-args] 
    (eval `(def ~(-> sym-exp eval symbol) [email protected]))) 

Если вы просто хотите создать кучу агентов, может быть что-то, как это будет работать:

(def servers 
    (vec (for [i (range 5)] 
     {:id i :value 4939}))) 

Тогда вы можете просто получить доступ к ним по индексу:

(servers 0) 
; => {:id 0, :value 4939} 
+0

Эй, я пытаюсь создать несколько агентов с разными именами. Я хочу создать, скажем, 6 агентов, которые имеют тип «сервер», поэтому каждый будет иметь имя: server0 . . server5 –

+1

@FengHuo - Если вы просто хотите сгенерировать кучу «серверных» переменных, почему бы просто не поместить их в вектор? Я верну свой ответ на примере. – DaoWen

1

времени выполнения эквивалент def является intern:

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

 Смежные вопросы

  • Нет связанных вопросов^_^