繁体   English   中英

在clojure中取消引用java方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM