简体   繁体   English

在clojure中取消引用java方法

[英]Unquote a java method in clojure

How do I parameterize calls methods in Clojure?如何在 Clojure 中参数化调用方法?

Example:示例:

(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

Right solution:正确的解决方法:

(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 [])

If you simply want to create an alias for an existing function, a wrapper function is all you need:如果您只想为现有函数创建别名,则只需要一个包装函数:

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

While you could use memfn as pointed out by another user, it seems less obvious what is going on.虽然您可以像其他用户指出的那样使用memfn ,但发生的事情似乎不太明显。 Indeed, even clojure.org recommends against it now:事实上,即使 clojure.org 现在也反对它:


https://clojure.org/reference/java_interop https://clojure.org/reference/java_interop

(memfn method-name arg-names)*

Macro.宏。 Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args.扩展为创建 fn 的代码,该 fn 期望传递一个对象和任何 args,并在传递 args 的对象上调用命名实例方法。 Use when you want to treat a Java method as a first-class fn.当您想将 Java 方法视为一流的 fn 时使用。

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

Note it almost always preferable to do this directly now, with syntax like:请注意,现在最好直接执行此操作,语法如下:

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

The normal way to parametrize a method on a Java class is:在 Java 类上参数化方法的正常方法是:

#(.method fixed-object %)

or

#(.method % fixed argument)

or if neither the object or the arguments are fixed.或者如果对象或参数都不是固定的。

#(.method %1 %2)

Often used with higher order functions line map, filter and reduce.通常与高阶函数 line map、filter 和 reduce 一起使用。

(map #(.getMoney %) customers)

Use memfn :使用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