我正在尝试将一些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)
答案 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)))))])