从 Clojure 调用一系列 Java 静态方法
Call series of Java static methods from Clojure
假设我遇到了一个 class,其中有几个我想连续调用的静态 setter 方法。我正在寻找的功能类似于 doto 提供的功能,除了它必须在 class 而不是对象上工作:
(doto MyClass
(setA "a")
(setB "b"))
不幸的是,当我尝试这个时,我得到 RuntimeException: Unable to resolve symbol: setA
。 class 是否有特殊的 doto
宏?
我将保留这个问题,因为我希望有更好的答案,但这是我的 home-grown 宏来解决这个问题:
(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")))
至
(do (. MyClass (setA "a"))
(. MyClass (setB "b")))
如何从 Clojure 调用静态 Java 方法?像这样...
(Classname/staticMethod 参数*)
例如,
> (System/getProperty "java.vm.version")
=> "25.141-b15"
我们想要一个宏,比如说 doto-static
,re-arranges 这个来自 (doto-static System (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"
假设我遇到了一个 class,其中有几个我想连续调用的静态 setter 方法。我正在寻找的功能类似于 doto 提供的功能,除了它必须在 class 而不是对象上工作:
(doto MyClass
(setA "a")
(setB "b"))
不幸的是,当我尝试这个时,我得到 RuntimeException: Unable to resolve symbol: setA
。 class 是否有特殊的 doto
宏?
我将保留这个问题,因为我希望有更好的答案,但这是我的 home-grown 宏来解决这个问题:
(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")))
至
(do (. MyClass (setA "a"))
(. MyClass (setB "b")))
如何从 Clojure 调用静态 Java 方法?像这样...
(Classname/staticMethod 参数*)
例如,
> (System/getProperty "java.vm.version")
=> "25.141-b15"
我们想要一个宏,比如说 doto-static
,re-arranges 这个来自 (doto-static System (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"