在clojure中取消引用java方法

时间:2016-10-26 13:35:42

标签: java methods clojure quote clojure-java-interop

如何在Clojure中参数化调用方法?

示例:

(def url (java.net.URL. "http://www.google.com"))
(.getHost url) ;; works!
(def host '.getHost)
(host url) ;; Nope :(
(~host url) ;; Nope :(
(eval `(~host url)) ;; Works :s

4 个答案:

答案 0 :(得分:1)

正确的解决方案:

(def url (URL. "http://www.google.com"))
(def host 'getHost)
(defn dynamic-invoke
  [obj method arglist]
  (.invoke (.getDeclaredMethod
             (class obj) (name method) nil)
           obj (into-array arglist)))
(dynamic-invoke url host [])

答案 1 :(得分:0)

如果您只是想为现有函数创建别名,那么您只需要一个包装函数:

> (ns clj (:import [java.net URL]))
> (def url (URL. "http://www.google.com"))
> (defn host [arg] (.getHost arg))
> (host url)
;=> "www.google.com"

虽然您可以使用其他用户指出的memfn,但似乎不太明显发生了什么。实际上,即使是clojure.org也建议现在反对它:

https://clojure.org/reference/java_interop

  

(memfn method-name arg-names)*

     

宏。扩展为创建期望的fn的代码   传递一个对象和任何args并调用命名实例方法   通过args的对象。在要处理Java方法时使用   作为一流的fn。

(map (memfn charAt i) ["fred" "ethel" "lucy"] [1 2 3])
-> (\r \h \y)
  

请注意,现在几乎总是可以直接执行此操作,语法如下:

(map #(.charAt %1 %2) ["fred" "ethel" "lucy"] [1 2 3])
-> (\r \h \y)

答案 2 :(得分:0)

在Java类上参数化方法的常规方法是:

#(.method fixed-object %)

#(.method % fixed argument)

或者如果对象或参数都没有修复。

#(.method %1 %2)

常用于高阶函数的线图,过滤和减少。

(map #(.getMoney %) customers)

答案 3 :(得分:-1)

使用memfn

(def url (java.net.URL. "http://www.google.com"))
(def host (memfn getHost))
(host url)