【问题标题】:Errors extending a Java Interface in Clojure在 Clojure 中扩展 Java 接口时出错
【发布时间】:2016-04-26 10:40:50
【问题描述】:

我有一个基本的 Java 接口定义如下:

public interface Action {
    void execute(Metadata var1, Parameter var2);
}

我正在尝试在 Clojure 中扩展它,但不断出错。将类导入我的命名空间后,我尝试使用reify,如下所示:

(defn action [action-fn]
  (reify Action
    (execute [metadata parameter] (action-fn metadata parameter))))

但这会引发编译器非法参数异常:

CompilerException java.lang.IllegalArgumentException: Can't define method not in interfaces: execute

接下来我尝试使用proxy

(defn action [action-fn]
  (proxy [Action] []
    (execute [metadata parameter] (action-fn metadata parameter))))

编译成功,我的编辑器(IntelliJ + Cursive)通过边框装饰导航到接口定义,但尝试在生成代理上调用执行失败:

(.execute (action (fn [_ _] "Test action")))

抛出以下内容:

IllegalArgumentException No matching field found: execute for class

最后我尝试使用 deftype 如下:

(deftype cljAction [action-fn]
  Action
  (execute [metadata parameter] (action-fn metadata parameter)))

引发与reify 相同的编译器错误,例如:

CompilerException java.lang.IllegalArgumentException: Can't define method not in interfaces: execute

浏览各种博客文章和 SO 答案似乎表明这是论点数量的问题,但我不知道如何解决它。我做错了什么??

【问题讨论】:

    标签: clojure


    【解决方案1】:

    您缺少函数中的 this 引用。所以你想要的是这样的:

    (defn action [action-fn]
      (reify Action
        (execute [this metadata parameter] (action-fn metadata parameter))))
    

    显然,因为您没有使用它,您可以将其称为 _ 或您认为最有意义的任何名称。当你调用你想要的函数时:

    (.execute (action action-fn) metadata parameter)
    

    这与您实现协议时略有不同。请参阅https://clojuredocs.org/clojure.core/definterface 了解更多信息。

    【讨论】:

    • 啊,成功了,谢谢!包括this 引用消除了编译器错误,REPL 中的以下代码按预期工作:(.execute (action (fn [metadata parameter] (println "Test action"))) nil nil)
    • @OliverMooney,很高兴为您提供帮助!
    【解决方案2】:

    ponzao 的回答是正确的。但请注意,Cursive 实际上可以为您填写存根:您可以编写 (reify Action) 然后(在该表单中的某处使用光标)选择 Code->Generate... 并选择实现方法.然后草书将用正确的形式填写存根。这目前仅在实现接口而非协议时有效。

    【讨论】:

    • 我没有意识到,谢谢!我主要使用 IntelliJ 作为 Cursive 的主机,到目前为止,大多数面向 Java 的菜单选项都是未知数...
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2011-01-14
    • 2012-12-19
    • 2012-10-23
    • 2018-11-28
    相关资源
    最近更新 更多