[英]How to call a reified Java interface from a class in Clojure? Call can't be resolved
I am trying to translate some Java code directly into Clojure on a raspberry pi. 我正在尝试将一些Java代码直接转换为树莓派上的Clojure。 I am stuck at implementing an interface in a method call - addListener.
我一直坚持在方法调用中实现接口-addListener。
I have tried using reify, proxy, and deftype. 我尝试使用reify,proxy和deftype。 With reify I have tried providing as many hints to the compiler as possible.
通过reify,我尝试为编译器提供尽可能多的提示。
This is the original Java code : 这是原始的Java代码 :
myButton.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
}
});
And this is my translated Clojure code: 这是我翻译的Clojure代码:
(.addListener myButton
(reify GpioPinListenerDigital
(^void handleGpioPinDigitalStateChangeEvent [this ^GpioPinDigitalStateChangeEvent event]
(println (str " --> GPIO PIN STATE CHANGE: " (.getPin event) " = " (.getState event))))))
I always end up with the same error: 我总是会遇到相同的错误:
IllegalArgumentException No matching method found: addListener for class com.pi4j.io.gpio.impl.GpioPinImpl clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:79)
IllegalArgumentException找不到匹配方法:com.pi4j.io.gpio.impl.GpioPinImpl clojure.lang.Reflector.invokeMatchingMethod类的addListener(Reflector.java:79)
I am not familiar with writing Java for raspberry pi, but looking at the javadoc we see the following declarations: 我不熟悉为树莓派编写Java,但是在Javadoc中,我们看到以下声明:
public void addListener(GpioPinListener... listener);
public void addListener(List<? extends GpioPinListener> listeners);
Both are accepting a multitude of listeners, not just one. 两者都接受众多的听众,而不仅仅是一个。 In the Java example you provided above, java compiler turns the single listener instance into a singelton vector transparently, and uses the first definition shown above.
在上面提供的Java示例中,java编译器透明地将单个侦听器实例转换为singelton向量,并使用上面显示的第一个定义。
The clojure compiler does not know how to do that, you have to help it. clojure编译器不知道该怎么做,您必须提供帮助。 The question essentially boils down to how to call variadic java functions from clojure .
这个问题本质上归结为如何从clojure调用可变参数的Java函数 。
Without testing this, I believe the solution will be using clojure's into-array
function, so something like the following: 如果不进行测试,我相信解决方案将使用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)))))]))
You may have to twist this a little bit, but I believe that is the core problem you are facing. 您可能需要稍微扭转一下,但是我认为这是您面临的核心问题。
Due to the second declaration above, another potential solution may simply be wrapping it in some regular list, such as a vector: 由于上面的第二个声明,另一个可能的解决方案可能只是将其包装在某些常规列表中,例如矢量:
(.addListener myButton
[(reify GpioPinListenerDigital
(^void handleGpioPinDigitalStateChangeEvent [this ^GpioPinDigitalStateChangeEvent event]
(println (str " --> GPIO PIN STATE CHANGE: " (.getPin event) " = " (.getState event)))))])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.