2014-10-06 222 views
2

我有一个向量值,比如[210 50 60],我需要用它创建Java对象。比如我要创建Color申请Java构造函数

(Color. 210 50 60)   ; standard way 
(apply Color. [210 50 60]) ; hmm... I need something like this 

当然Color.的是不是一个功能,我们不能用就可以了apply。有没有办法解决这个任务的一种优雅的方式或做我必须把它写这样的:

(let [[r g b] [210 50 60]] 
    (Color. r g b)) 
+0

如何有一个3 int作为参数的构造函数? – Marco 2014-10-06 08:55:32

+2

我认为最接近的做法是制作一个lambda包装:'(apply#(Color。%1%2%3)...)' – 2014-10-06 08:55:52

+0

@Marco,它不会比'let'更好。很显然,这样的包装只是一种方式,以某种方式使用“应用”在先验无用的环境中。我想,正确的解决方案就是某种标准宏。 – Mark 2014-10-06 08:59:55

回答

1

如果你不介意支付反射成本,我认为https://stackoverflow.com/a/9172515/151650是一种优雅的方式。 如果你不介意疯狂的宏:

(defn arity [c i] 
    (let [args (map #(symbol (str "arg" %)) (range i))] 
    `([[email protected]] (new ~c [email protected])))) 

(defmacro ->c [c] 
    (let [cs (.getConstructors (resolve c)) 
     arities (set (map #(count (.getParameterTypes %)) cs)) 
     fn-arities (map #(arity c %) arities)] 
    `(fn [email protected]))) 

(apply (->c java.awt.Color) 1 [2 3]) 
+0

谢谢,我不认为这是可能的...虽然现在我更喜欢简单的解决方案与'let'。 – Mark 2014-10-06 15:13:56