[英]Unquote a java method in clojure
如何在 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
正确的解决方法:
(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 [])
如果您只想为现有函数创建别名,则只需要一个包装函数:
> (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 的代码,该 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)
在 Java 类上参数化方法的正常方法是:
#(.method fixed-object %)
或
#(.method % fixed argument)
或者如果对象或参数都不是固定的。
#(.method %1 %2)
通常与高阶函数 line map、filter 和 reduce 一起使用。
(map #(.getMoney %) customers)
使用memfn
:
(def url (java.net.URL. "http://www.google.com"))
(def host (memfn getHost))
(host url)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.