Clojure宏:在宏中执行代码

Clojure宏:在宏中执行代码,clojure,macros,Clojure,Macros,我想创建一个宏,这样我就可以在变量本身中添加变量名。我有这个单元记录。它的name成员存储将要创建的变量的名称。 i、 e.如(def a-变量(->1号机组1“a-变量”) 但是我不想自己传递变量名 我认为宏可以派上用场。:) 代码如下: (defrecord Unit [value gradient name] Object (toString [_] (str name " : "))) (defmacro create-unit1 [var-name &am

我想创建一个宏,这样我就可以在变量本身中添加变量名。我有这个
单元
记录。它的
name
成员存储将要创建的变量的名称。 i、 e.如
(def a-变量(->1号机组1“a-变量”)
但是我不想自己传递变量名

我认为宏可以派上用场。:)

代码如下:

(defrecord Unit 
    [value gradient name]
  Object
  (toString [_]
    (str name " : ")))


(defmacro create-unit1 [var-name & body]
  `(def ~var-name ~(concat body (list (name var-name)))))

(defmacro create-unit2 [var-name & body]
  `(def ~var-name (concat ~@body (list (name '~var-name)))))
但他们都没有给我写代码:

neurals.core> (macroexpand '(create-unit1 a (->Unit 1.0 0.0)))
(def a ((->Unit 1.0 0.0) "a"))

neurals.core> (macroexpand '(create-unit2 a (->Unit 1.0 0.0)))
(def a (clojure.core/concat 
       (->Unit 1.0 0.0) (clojure.core/list 
                           (clojure.core/name (quote a)))))
neurals.core> 
我想要:

(def a (->Unit 1.0 0.0 (clojure.core/name (quote a))))

在宏中执行
concat
的正确方法是什么?

您可以通过删除
创建单元1中的
来修复代码:

(defmacro create-unit1 [var-name body]
  `(def ~var-name ~(concat body (list (name var-name)))))

(macroexpand `(create-unit1 a (->Unit 1.0 1.0)))
;; => (def user/a (user/->Unit 1.0 1.0 "a"))
您还可以添加一点语法糖:

(defmacro create-unit1 [var-name body]
  `(def ~var-name (~@body ~(name var-name))))
或者,为了让所有这些更加地道:

(defmacro defunit [sym value gradient]
  `(def ~sym (->Unit ~value ~gradient ~(name sym))))

(defunit a 1.0 1.0)
;; => #user.Unit{:value 1.0, :gradient 1.0, :name "a"}
哦<代码>(~@body~(name-var-name))
是连接它的方法:)。。凉爽的