5

Un sacco di metodi JavaFX prendono args var, come gruppo, che è dichiarato in Java come:Clojure e JavaFX 2 - passaggio di argomenti a più Arity ai metodi JavaFX

public Group(Node... children) 

Altri, ad esempio:

public KeyFrame(Duration time, KeyValue... values) 

ho scoperto il ... significa che dovrei passare un array di Java per il metodo, quindi ho fatto cose come questa,

(-> timeline .getKeyFrames 
    (.addAll 
    (into-array [(KeyFrame. blabla) (KeyFrame. blabla)]))` 

E 'fastidioso dover fare (into-array...) ogni volta che c'è una var arg, ed è più fastidioso quando la var arg è una classe base di quello che sto realmente passando. Ad esempio

(Group. (into-array [(Circle. 100) (Rectangle. 100 100)])) 

risultati in Tipo errore di disallineamento. Invece devo fare questo:

(Group. (into-array Node [(Circle. 100) (Rectangle. 100 100)])) 

Così ho fatto questa funzione:

(defn make-group [& items] 
    (Group. (into-array Node items))) 

che va bene per i gruppi, ma non risolve il problema generale.

Quindi c'è un buon modo di risolvere il problema di ellissi/vararg in modo da non dover creare funzioni speciali per ogni metodo vararg? I requisiti per questa funzione consistono nel prendere il metodo che si desidera chiamare (ad es. Group), gli argomenti fissi, gli argomenti di variabile e in qualche modo magicamente la funzione saprebbe trovare la classe di base comune degli elementi nelle variabili var.

Grazie

risposta

2

Hai provato a mettere gli argomenti in un vettore? Non ho provato tutti i casi d'uso che hai menzionato, ma quando uso il metodo addAll() per esempio ho semplicemente messo gli argomenti in un vettore letterale, ad es.

(.addAll (.getChildren btn-pane) [new-puzzle-pane check-box hint-btn 
            check-btn solve-btn load-btn save-btn 
            print-btn about-btn spacer]) 
+0

passano vettori sia direttamente quello che ho provato prima e ottenuto 'Numero errato di argomenti (0) passato a: PersistentVector' – Sonicsmooth

1

Finii utilizzando una macro, che tipo di sospettavo bisogno:

(defmacro jvar [method & args] 
    (let [lastargs (last args) 
     evaled-lastargs (eval lastargs)] 
    (if (coll? evaled-lastargs) 
     (let [firstargs (butlast args) 
      klass (eval (last firstargs)) 
      supset (map #(supers (class %)) evaled-lastargs) 
      common (apply intersection #{klass} supset)] 
     (if (seq common) 
      `(~method [email protected](butlast firstargs) (into-array ~(first common) ~lastargs)) 
      `(~method [email protected] (into-array ~lastargs))))))) 

Uso simili:

(jvar Group. Node [(Circle. 100) (Rectangle. 10 10)])