2011-01-02 8 views
9

Come si imposta il codice fattore in molti campi diversi in un oggetto Java? Vorrei fattoreCodice fattore Clojure che imposta molti campi diversi in un oggetto Java

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

a

(doseq [field '((name "Chris") (age 100) (salary 5000))] 
    (set! (. employee (first field)) (second field))) 

Tuttavia questo non funziona perché il periodo è una macro, e cerca di valutare (primo campo), letteralmente. A proposito, capisco che i campi di impostazione non sono una buona pratica. Ho bisogno di interagire con il codice legacy.

risposta

7

tenta di utilizzare setter - ma se non hai scelta e davvero bisogno di fatelo notare, una macro come questa farebbe:

(defmacro set-all [object & fields-and-values] 
    (let [obj-sym (gensym)] 
    `(let [~obj-sym ~object] 
     [email protected](for [[field value] (partition 2 fields-and-values)] 
      `(set! (. ~obj-sym ~field) 
        ~value))))) 

Il gensym è necessario nel caso in cui l'oggetto che produce un'espressione abbia effetti collaterali.

Esempio di utilizzo:

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]> 
5

Si potrebbe provare:

(defmacro set-all! [obj m] 
    `(do [email protected](map (fn [e] `(set! (. ~obj ~(key e)) ~(val e))) m) ~obj)) 

Esempio:

(def a (java.awt.Point.)) 
(set-all! a {x 300 y 100}) 

Macroexpand-all:

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

Nessun tali metodi esistono. – chris

+0

Ah, stai impostando i campi. Colpa mia per non aver prestato attenzione. Ho aggiornato la mia risposta. – Psyllo

Problemi correlati