【问题标题】:Unquote a java method in clojure在clojure中取消引用java方法
【发布时间】:2023-04-05 21:30:02
【问题描述】:

如何在 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

【问题讨论】:

  • 由于'.getHost 不是一开始就“引用的方法”,因此您不能取消引用它。这只是一个象征。此外,您似乎已经想出了如何将您的符号评估为方法调用,那么问题是什么?
  • 最后一行吓到我了!万圣节快乐!

标签: java methods clojure quote clojure-java-interop


【解决方案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】:

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

    > (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 的代码 传递一个对象和任何参数并调用命名实例方法 传递参数的对象。当您想处理 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)
    

    【讨论】:

      【解决方案3】:

      对 Java 类的方法进行参数化的常规方法是:

      #(.method fixed-object %)
      

      #(.method % fixed argument)
      

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

      #(.method %1 %2)
      

      通常与高阶函数 line map、filter 和 reduce 一起使用。

      (map #(.getMoney %) customers)
      

      【讨论】:

        【解决方案4】:

        使用memfn:

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

        【讨论】:

        • 我忘记了memfn
        • memfn 在 Clojure 1.0 时代被贬低了。它被 #(.methodname thing args args) 形式取代
        • 这个亚瑟的来源?
        猜你喜欢
        • 2017-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-20
        相关资源
        最近更新 更多