如何在Clojure中的类中调用Java化接口?通话无法解决

时间:2018-12-20 20:13:56

标签: java interface clojure interop reify

我正在尝试将一些Java代码直接转换为树莓派上的Clojure。我一直坚持在方法调用中实现接口-addListener。

我尝试使用reify,proxy和deftype。通过reify,我尝试为编译器提供尽可能多的提示。

这是原始的Java code

myButton.addListener(new GpioPinListenerDigital() {
  @Override
  public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
  System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
 }
});

这是我翻译的Clojure代码:

(.addListener myButton
              (reify GpioPinListenerDigital
                (^void handleGpioPinDigitalStateChangeEvent [this ^GpioPinDigitalStateChangeEvent event]
                 (println (str " --> GPIO PIN STATE CHANGE: " (.getPin event) " = " (.getState event))))))

我总是会遇到相同的错误:

  
    

IllegalArgumentException未找到匹配方法:com.pi4j.io.gpio.impl.GpioPinImpl类的addListener clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:79)

  

1 个答案:

答案 0 :(得分:0)

我不熟悉为树莓派编写Java,但在javadoc中,我们看到以下声明:

public void addListener(GpioPinListener... listener);
public void addListener(List<? extends GpioPinListener> listeners);

两者都接受大量的听众,而不仅仅是一个。在上面提供的Java示例中,java编译器透明地将单个侦听器实例转换为singelton向量,并使用上面显示的第一个定义。

clojure编译器不知道该怎么做,您必须提供帮助。这个问题基本上可以归结为how to call variadic java functions from clojure

未经测试,我相信解决方案将使用clojure的into-array函数,因此如下所示:

(.addListener myButton
              (into-array GpioPinListenerDigital
                [(reify GpioPinListenerDigital
                  (^void handleGpioPinDigitalStateChangeEvent [this ^GpioPinDigitalStateChangeEvent event]
                   (println (str " --> GPIO PIN STATE CHANGE: " (.getPin event) " = " (.getState event)))))]))

您可能需要稍微扭转一下,但是我认为这是您面临的核心问题。

编辑

由于上面的第二个声明,另一个可能的解决方案可能只是将其包装在某些常规列表中,例如向量:

(.addListener myButton
              [(reify GpioPinListenerDigital
                (^void handleGpioPinDigitalStateChangeEvent [this ^GpioPinDigitalStateChangeEvent event]
                 (println (str " --> GPIO PIN STATE CHANGE: " (.getPin event) " = " (.getState event)))))])