2015-05-01 8 views
6

This answer do bardzo starej pytanie o współdziałanie Clojure-Java wyjaśnia, jak korzystać gen-class z :state i :init słów kluczowych, aby utworzyć pojedynczą instancję zmiennej publiczną dostępną z poziomu Javy. Jest to wystarczające, jeśli potrzebujesz tylko jednego elementu danych, aby był dostępny dla klas Java, lub jeśli możesz wymagać, aby klasy Javy używały funkcji akcesyjnych, które odczytują, na przykład, mapę przechowywaną w zmiennej stanu. Ta metoda umożliwia również zmianę danych, np. przez przechowywanie atom s w zmiennej stanu.Jak utworzyć wiele zmiennych składowych Java z Clojure jest gen klasy

Co jeśli chcę utworzyć więcej niż jedną instancyjną zmienną, którą można bezpośrednio odczytać w klasie Java? czy to możliwe? Na przykład mogę skompilować następujące pliki i wykonać klasę Bar i zobaczyć wartość 42 z foo.bar wydrukowaną.

Foo.clj:

(ns students.Foo 
    (:gen-class 
    :name students.Foo 
    :state bar 
    ; :state baz 
    :init init)) 

(defn -init 
    [] 
    [[] 42]) 

Bar.java:

package students; 

public class Bar { 

    public static void main(String[] args) { 
     Foo foo = new Foo(); 
     System.out.println(foo.bar); 
     // System.out.println(foo.baz); 
    } 
} 

Gdybym odkomentowaniu baz linie Bar.java nie będzie skompilować - kompilator wydaje się losowo tworzyć albo bar lub baz jako zmienną stanu dla Foo, więc tylko jedna z nich jest dostępna dla Bar. I w żadnym wypadku nie widzę, jak zainicjować zarówno bar i baz przy użyciu funkcji init.

Odpowiedz

2

Makro gen-class nie obsługuje definiowania więcej niż jednego pola publicznego. Zamiast tego należy użyć makra defrecord lub deftype.

(defrecord Foo [bar baz]) 

Niestety, zarówno defrecord makro i deftype makro nie przygotowuje drogę do zdefiniowania ich konstruktorów. Tak więc, gdy inicjowanie wielu zmiennych instancji jest obowiązkowe, nie ma wstydu w pisaniu klasy Java w Javie.

+0

Dzięki. Bez wstydu, ale bez zabawy; Wolę pisać Clojure. To rozczarowuje. Biorąc pod uwagę wszystkie funkcje, które Clojure zapewnia dla interakcji z Javą, wydaje się to arbitralnym ograniczeniem. Wiele zmiennych instancji może nie być dla mnie obowiązkowych, na szczęście, ale chciałem wiedzieć. – Mars

+0

Na podstawie schematu blokowego Chas Emerick dotyczącego wyboru właściwego formularza definicji typu Clojure (http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form), 'gen-class' jest prawdopodobnie najlepszą opcją dla mojego obecnego projektu. – Mars

Powiązane problemy