Tôi đang cố gắng chuyển đổi trực tiếp một số mã Java thành Clojure trên Raspberry Pi. Tôi nhấn mạnh vào việc triển khai giao diện trong lệnh gọi phương thức - addListener.
Tôi đã thử sử dụng reify, proxy và deftype. Với reify, tôi cố gắng cung cấp càng nhiều gợi ý càng tốt cho trình biên dịch.
Đây là bản gốcMã Java :
myButton.addListener(GpioPinListenerDigital mới() {
@Ghi đè
public void xử lýGpioPinDigitalStateChangeEvent(sự kiện GpioPinDigitalStateChangeEvent) {
System.out.println(" --> THAY ĐỔI TRẠNG THÁI PIN GPIO: " + event.getPin() + " = " + event.getState());
}
});
Đây là mã Clojure đã dịch của tôi:
(.addListener myButton
(cụ thể hóa GpioPinListenerDigital
(^void HandleGpioPinDigitalStateChangeEvent [sự kiện ^GpioPinDigitalStateChangeEvent này]
(println (str " --> THAY ĐỔI TRẠNG THÁI PIN GPIO: " (sự kiện .getPin) " = " (sự kiện .getState))))))
Tôi luôn gặp lỗi tương tự:
IllegalArgumentException Không tìm thấy phương thức khớp: addListener cho lớp com.pi4j.io.gpio.impl.GpioPinImpl clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:79)
Tôi không quen viết Java cho Raspberry Pi nhưng hãy xemjavadocChúng ta thấy tuyên bố sau:
public void addListener(GpioPinListener... listen);
public void addListener(Danh sách mở rộng trình nghe GpioPinListener>);
Cả hai đều chấp nhận một lượng lớn khán giả chứ không chỉ một. Trong ví dụ Java được cung cấp ở trên, trình biên dịch Java chuyển đổi một cách trong suốt một phiên bản trình nghe thành một vectơ duy nhất, sử dụng định nghĩa đầu tiên được hiển thị ở trên.
Trình biên dịch clojure không biết cách thực hiện việc này, bạn phải trợ giúp nó. Vấn đề này về cơ bản tóm lại là cách gọi các hàm java đa dạng từ clojure .
Nếu không kiểm tra điều này, tôi tin rằng giải pháp sẽ là sử dụng clojure vào mảng
chức năng, vì vậy một cái gì đó như sau:
(.addListener myButton
(GpioPinListenerDigital thành mảng
[(cụ thể hóa GpioPinListenerDigital
(^void HandleGpioPinDigitalStateChangeEvent [sự kiện ^GpioPinDigitalStateChangeEvent này]
(println (str " --> THAY ĐỔI TRẠNG THÁI PIN GPIO: " (sự kiện .getPin) " = " (sự kiện .getState)))))]))
Bạn có thể cần phải đảo ngược điều này một chút, nhưng tôi tin rằng đây là vấn đề cốt lõi mà bạn đang gặp phải.
biên tập
Do tuyên bố thứ hai ở trên, một giải pháp tiềm năng khác có thể chỉ là đưa nó vào một danh sách thông thường nào đó, như vector:
(.addListener myButton
[(cụ thể hóa GpioPinListenerDigital
(^void HandleGpioPinDigitalStateChangeEvent [sự kiện ^GpioPinDigitalStateChangeEvent này]
(println (str " --> THAY ĐỔI TRẠNG THÁI PIN GPIO: " (sự kiện .getPin) " = " (sự kiện .getState)))))])
Giới thiệu về java - Làm cách nào để gọi giao diện Java được thể hiện từ một lớp trong Clojure? Gọi cuộc gọi không giải quyết được, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/53875417/
Tôi là một lập trình viên xuất sắc, rất giỏi!