如何在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
答案 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)