使用reify的Clojure Java互操作没有匹配方法

时间:2019-05-10 01:20:32

标签: clojure clojure-java-interop

我对某个Clojure / Java互操作有误解。

我正在使用Pi4J库,我想在GPIO引脚上获得一个侦听器。

使用文档:https://pi4j.com/1.2/usage.html(在“侦听引脚更改”下)给出以下示例:

public static class GpioUsageExampleListener implements GpioPinListenerDigital {
    @Override
    public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
        // display pin state on console
        System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = "
                + event.getState());
    }
}

// create and register gpio pin listener
myButton.addListener(new GpioUsageExampleListener());

还有一个示例应用程序:https://pi4j.com/1.2/example/listener.html

具有:

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

因此,我正在尝试以下Clojure代码:

(import [com.pi4j.io.gpio GpioFactory GpioPinDigitalInput PinPullResistance RaspiPin]
        [com.pi4j.io.gpio.event GpioPinListenerDigital])

(def gpio (GpioFactory/getInstance))
(def mybutton (.provisionDigitalInputPin gpio RaspiPin/GPIO_02 PinPullResistance/PULL_DOWN))

(def gpio-listener (reify GpioPinListenerDigital
                    (handleGpioPinDigitalStateChangeEvent [this event]
                      (println "GPIO Event Occured"))))

(.addListener mybutton gpio-listener)

但是我得到:

No matching method addListener found taking 1 args for class com.pi4j.io.gpio.impl.GpioPinImpl

使用反射,我了解了mybutton实例可用的方法,并且可以看到该方法在其中:

(clojure.reflect/reflect mybutton)

 :members
 #{{ 
    ;;; Stuff trimmed
   {:name addListener,
    :return-type void,
    :declaring-class com.pi4j.io.gpio.impl.GpioPinImpl,
    :parameter-types [java.util.List],
    :exception-types [],
    :flags #{:public :synchronized}}
   {:name addListener,
    :return-type void,
    :declaring-class com.pi4j.io.gpio.impl.GpioPinImpl,
    :parameter-types [com.pi4j.io.gpio.event.GpioPinListener<>],
    :exception-types [],
    :flags #{:varargs :public :synchronized}}}}

我已经针对GpioPinListener成功检查了gpio-listener的类型。

(cast com.pi4j.io.gpio.event.GpioPinListener gpio-listener)
#object[user$reify__7404 0x11251bd "user$reify__7404@11251bd"]

我尝试将类型的参数提示给GpioPinListener,但得到的结果相同。

由于我缺乏Clojure和Java知识,这使我感到失望,因此我对下一步的工作有些迷茫,但是我敢肯定这是非常基础的事情。

1 个答案:

答案 0 :(得分:3)

我无法对此进行测试,但是如果您注意到the docs,您会发现addListener实际上是var-arg,而处理var-arg方法可能会使{{3} }。

addListener期望一个监听器的 array (通过Java var-arg语法得以解决)。试试

(.addListener mybutton
              (into-array [gpio-listener])) 

或者,由于addListener实际上有一个List重载,因此这可能也可以工作

(.addListener myButton [gpio-listener])