Как вызвать интерфейс Java из класса в Clojure?Звонок не может быть решен - PullRequest
0 голосов
/ 20 декабря 2018

Я пытаюсь перевести некоторый код Java прямо в Clojure на Raspberry Pi.Я застрял при реализации интерфейса в вызове метода - addListener.

Я пытался использовать reify, proxy и deftype.С помощью reify я попытался предоставить как можно больше подсказок компилятору.

Это оригинальный Java-код :

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 Метод поиска не найден: addListener для класса com.pi4j.io.gpio.impl.GpioPinImpl clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:79)

1 Ответ

0 голосов
/ 21 декабря 2018

Я не знаком с написанием Java для Raspberry Pi, но, глядя на javadoc , мы видим следующие объявления:

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

Оба принимают множество слушателей, а не толькоодин.В приведенном выше примере с Java Java-компилятор прозрачно превращает отдельный экземпляр прослушивателя в вектор сингелтона и использует первое определение, показанное выше.

Компилятор clojure не знает, как это сделать, вы должны помочь ему.По сути, вопрос сводится к , как вызывать переменные Java-функции из 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)))))])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...