有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在clojure中取消引用java方法

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

  1. # 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 [])
    
  2. # 2 楼答案

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

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

    虽然你可以像另一个用户所指出的那样使用memfn,但发生的事情似乎不那么明显。事实上,即使是克罗朱尔。org建议现在不要这样做:


    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. Use when you want to treat a Java method as a first-class 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)
    
  3. # 3 楼答案

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

    #(.method fixed-object %)
    

    或者

    #(.method % fixed argument)
    

    或者如果对象或参数都不固定

    #(.method %1 %2)
    

    常用于高阶函数的线映射、滤波和归约

    (map #(.getMoney %) customers)
    
  4. # 4 楼答案

    使用memfn

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