Варианты создания классов Java в Clojure

Существует несколько различных способов создания классов Java в Clojure, так каковы компромиссы при выборе между gen-class? , proxy и reify в Clojure? (есть ли другие способы создания классов Java, которые я не перечислил?)

Мое основное понимание состоит в том, что я перечислил эти конструкции в порядке убывания мощности.


person pauldoo    schedule 29.04.2011    source источник


Ответы (2)


Используйте gen-class, когда вам нужен именованный класс или вы хотите добавить новые методы к создаваемым вами объектам. gen-class полагается на компиляцию AOT.

Если вам нужна анонимная одноразовая реализация типа, вы используете reify или proxy. Они не полагаются на компиляцию AOT. Вот их отличия:

  1. reify поддерживает только протоколы или интерфейсы, proxy также поддерживает конкретные суперклассы.
  2. reify использует настоящие методы класса, proxy использует внешние функции.
  3. Из-за № 2 reify использует прямой поиск метода, а proxy использует карту для поиска метода.
  4. Из-за #3 reify не поддерживает динамическую замену методов, а proxy поддерживает.

reify будет работать лучше, чем proxy, поэтому по возможности следует всегда использовать reify. Используйте proxy только тогда, когда ограничения reify слишком строгие.

person dbyrne    schedule 29.04.2011

Помимо gen-class, proxy и reify, у нас есть derecord и deftype. Эти последние два варианта должны быть вашим первым выбором для создания именованных классов Java (и в случае дезаписи ваш первый выбор для любого типа структуры с именованными компонентами).

страница типов данных на clojure.org является хорошим справочником по этой теме. Defrecord, deftype и reify новее, чем gen-class и proxy, они были представлены в версии 1.2 (я думаю, возможно, 1.1). Defrecord и deftype создают классы, соответствующие интерфейсам, но не допускающие наследования. Если вам нужно наследование, gen-class (и прокси для анонимных классов) по-прежнему ваш единственный вариант.

Defrecord и deftype отличаются тем, что вам даются бесплатно. Defrecord автоматически создает класс, соответствующий IPersistentMap и ISeq. Deftype, с другой стороны, дает вам больше контроля над вашим классом, даже допуская изменяемые поля (что не разрешено в дезаписи). В общем, deftype предназначен для низкоуровневой реализации структур данных, тогда как defrecord предназначен для повседневного использования.

person Rob Lachlan    schedule 29.04.2011