Добавить конструктор в deftype созданный класс
Для целей взаимодействия с Java мне нужен класс с нулевым конструктором, который выполняет инициализацию. У объектов этого класса должно быть что-то, похожее на изменяемые поля Java (а именно, объект представляет бэкэнд игры и должен сохранять игровое состояние).
deftype делает все, что я хочу, за исключением предоставления нулевого конструктора (так как я создаю класс с полями).
Мне не нужно, чтобы поля были общедоступными, поэтому я могу придумать 4 решения:
Используйте gen-класс; Я не хочу этого делать, если смогу избежать этого.
Каким-то образом кодировать закрытые переменные-члены вне знания deftype; Мне сказали, что это невозможно сделать.
Написание модифицированного deftype, который также создает нулевой конструктор; честно говоря, я не знаю достаточно хорошо clojure для этого.
Взять класс, созданный deftype, и каким-то образом добавить в него новый конструктор.
В конце этого мне нужно иметь класс Java, так как я буду передавать его Java-коду, который будет создавать новый объект из класса.
Являются ли какие-либо решения, которые я предложил (или те, о которых я не думал), кроме использования gen-class, жизнеспособными?
2 ответа
Там, где это уместно, нет ничего постыдного в написании черты Java, если ваши требования к взаимодействию Java одновременно специфичны и непоколебимы. Вы можете написать класс Java с помощью одного статического метода фабрики, который возвращает экземпляр deftype
класс, и это делает любую инициализацию / настройку, что вам нужно.
В качестве альтернативы, вы можете написать нулевую фабричную функцию в Clojure и вызывать ее напрямую из Java весь день.
Ни в коем случае ни deftype
ни defrecord
предназначены для (или будут ли они) полнофункциональными средствами взаимодействия. gen-class
конечно, ближе всего, поэтому это было рекомендовано.
Я бы предложил просто написать объект на Java - для Java-подобных объектов с изменяемыми полями это, вероятно, будет более элегантным, понятным и практичным.
У меня, как правило, были довольно хорошие результаты по смешиванию кода Java и Clojure в проектах. Это похоже на один из тех случаев, когда это может быть уместно. Функциональная совместимость настолько хороша, что у вас практически нет дополнительных сложностей.
Кстати, я предполагаю, что вам нужен нулевой конструктор, чтобы соответствовать требованиям некоторой персистентной библиотеки или чего-то подобного? В противном случае это кажется странным требованием. Если это так, то вы можете найти, что имеет смысл переосмыслить вашу стратегию персистентности... произвольные ограничения, подобные этому, всегда кажутся мне чем-то вроде запаха кода.