Factor Clojure代码在Java对象中设置许多不同的字段

Factor Clojure代码在Java对象中设置许多不同的字段,clojure,field,Clojure,Field,如何在Java对象中设置多个不同的字段?我想考虑一下 (set! (. employee name) "Chris") (set! (. employee age) 100) (set! (. employee salary) 5000) 到 但是,这将不起作用,因为周期是一个宏,并且试图按字面意思计算(第一个字段)。顺便说一句,我知道设置字段不是好的做法。我需要与旧代码交互操作。您可以尝试: (defmacro set-all! [obj m] `(do ~@(map (fn [e]

如何在Java对象中设置多个不同的字段?我想考虑一下

(set! (. employee name) "Chris")
(set! (. employee age) 100)
(set! (. employee salary) 5000)

但是,这将不起作用,因为周期是一个宏,并且试图按字面意思计算(第一个字段)。顺便说一句,我知道设置字段不是好的做法。我需要与旧代码交互操作。

您可以尝试:

(defmacro set-all! [obj m]
    `(do ~@(map (fn [e] `(set! (. ~obj ~(key e)) ~(val e))) m) ~obj))
例如:

(def a (java.awt.Point.))
(set-all! a {x 300 y 100})
宏扩展全部:

(do (set! (. a x) 9)
    (set! (. a y) 7)
    a)

尝试使用setter-但是如果您没有选择,并且确实需要考虑到这一点,那么像这样的宏可以:

(defmacro set-all [object & fields-and-values]
  (let [obj-sym (gensym)] 
    `(let [~obj-sym ~object]
        ~@(for [[field value] (partition 2 fields-and-values)]
           `(set! (. ~obj-sym ~field)
                  ~value)))))
如果产生对象的表达式有任何副作用,则需要gensym

用法示例:

user> (def p (java.awt.Point.))
#'user/p
user> (set-all p x 4 y 5)
5
user> p
#<Point java.awt.Point[x=4,y=5]>
user>(defp(java.awt.Point.))
#'用户/p
用户>(设置所有p x 4 y 5)
5.
用户>p
#
user> (def p (java.awt.Point.))
#'user/p
user> (set-all p x 4 y 5)
5
user> p
#<Point java.awt.Point[x=4,y=5]>