5

很多 JavaFx 方法都采用 var args,例如 Group,在 Java 中声明为:

public Group(Node... children)

其他例如:

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

我发现了...应该将 java 数组传递给方法的方法,所以我一直在做这样的事情,

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

每次有 var arg 时都必须这样做很(into-array...)烦人,而当 var arg 是我实际传入的基类时更烦人。例如

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

导致类型不匹配错误。相反,我必须这样做:

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

所以我做了这个功能:

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

这对组很好,但不能解决一般问题。

那么有没有解决椭圆/可变参数问题的好方法,所以我不必为每个可变参数方法制作特殊功能?这个函数的要求是它需要你想要调用的方法(例如Group),固定的参数,可变参数,并且不知何故,该函数会神奇地知道在可变参数中找到元素的公共基类。

谢谢

4

2 回答 2

2

您是否尝试过将参数放入向量中?我还没有尝试过您提到的所有用例,但是例如在使用 addAll() 方法时,我只是将参数放入文字向量中,例如

    (.addAll (.getChildren btn-pane) [new-puzzle-pane check-box hint-btn
                                  check-btn solve-btn load-btn save-btn
                                  print-btn about-btn spacer])
于 2013-05-29T12:12:59.653 回答
1

我最终使用了一个宏,我有点怀疑我需要它:

(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 ~@(butlast firstargs) (into-array ~(first common) ~lastargs))
          `(~method ~@firstargs (into-array ~lastargs)))))))

像这样的用法:

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

于 2013-05-29T19:17:42.640 回答