从Clojure调用一系列Java静态方法

从Clojure调用一系列Java静态方法,clojure,clojure-java-interop,Clojure,Clojure Java Interop,假设我遇到了一个包含几个静态setter方法的类,我想连续调用这些方法。我正在寻找的功能与doto提供的功能类似,只是它必须在类而不是对象上工作: (doto MyClass (setA "a") (setB "b")) 不幸的是,当我尝试这样做时,我得到了RuntimeException:无法解析symbol:setA。类是否有一个特殊的doto宏?我将保留这个问题,因为我希望有一个更好的答案,但下面是我自己开发的宏来解决这个问题: (defmacro doto-cl

假设我遇到了一个包含几个静态setter方法的类,我想连续调用这些方法。我正在寻找的功能与doto提供的功能类似,只是它必须在类而不是对象上工作:

(doto MyClass
      (setA "a")
      (setB "b"))

不幸的是,当我尝试这样做时,我得到了
RuntimeException:无法解析symbol:setA
。类是否有一个特殊的
doto
宏?

我将保留这个问题,因为我希望有一个更好的答案,但下面是我自己开发的宏来解决这个问题:

(defmacro doto-class
  "Calls a series of static methods on a class"
  [klass & forms]
  (cons 'do
        (for [f forms]
          `(. ~klass ~f))))
这扩展了示例:

(macroexpand-1
 '(doto-class MyClass
              (setA "a")
              (setB "b")))


如何从Clojure调用静态Java方法?像这样

(Classname/staticMethod args*)

比如说,

> (System/getProperty "java.vm.version")

=> "25.141-b15"
我们需要一个宏,比如说
doto static
,它可以从
(doto static系统(getProperty“java.vm.version”)
重新安排它,还允许一系列调用

这样的宏是

(defmacro doto-static [class-symbol & calls]
  (let [qualify (fn [method-symbol] (->> method-symbol
                                    (name)
                                    (str (name class-symbol) \/)
                                  (symbol)))
        elaborate (fn [[method-symbol & arg-exprs]]
                      (cons (qualify method-symbol) arg-exprs))]
          (cons 'do (map elaborate calls))))
比如说,

> (doto-static System (getProperty "java.vm.version") (getProperty "java.vm.version"))

=> "25.141-b15"

我的大脑因工作而兴奋,但我什么都想不出来,我写的宏基本上和你的一样。我怀疑这是一个如此罕见的用例,以至于它没有被考虑。我不认为我需要对静态方法的调用进行排序。很有趣!您知道这个宏是否比我之前发布的简单解决方案有好处吗?如果是这样的话,这将是对这个答案的一个很好的补充。@user12341234您的答案更干净。它所拥有的唯一优势是符合法律。我不明白你回答的要点,否则我就不会把这个贴出来了。
> (doto-static System (getProperty "java.vm.version") (getProperty "java.vm.version"))

=> "25.141-b15"