Разница между структурой и классом в Common Lisp
Мое понимание структуры состоит в том, что она имеет слоты для хранения данных, имеет тип, имеет make-X
и функции доступа к слотам, и могут быть специализированы по методу (так как он имеет тип).
Мое понимание класса состоит в том, что у него все одинаковое и множественное наследование. Главный ответ на этот вопрос гласит, что структуры могут иметь единственное наследование, и что начальные реализации CLOS были "намного медленнее", чем структуры.
Исходя из того, как люди говорят о CLOS и структурах, я предполагаю, что должны быть некоторые другие различия, но мои тривиальные поиски в Google были бесплодными. Поэтому я спрашиваю: каковы практические различия между CLOS и структурами?
2 ответа
сооружения
Структуры более примитивны. Они предоставляют то, что часто называют записью на языках программирования. Они были изобретены до занятий. CLtL1 (первая книга, описывающая Common Lisp) в 1984 году уже имела структуры, а позже была добавлена стандартная объектная система под названием CLOS. Структуры обеспечивают
- краткое определение макроса
DEFSTRUCT
- одиночное наследство
- быстрый доступ к слотам
- определяет читателя и setf доступ для слотов
- определяет предикат типа
- определяет функцию конструктора
- определяет функцию копирования
- печатное представление: структуры могут быть прочитаны и напечатаны
- выше функции могут быть встроены
полезные дополнения:
- DEFSTRUCT может определять списковые и векторные представления структур в дополнение к типам структур
Ограничения:
- после изменения типа структуры экземпляры структуры не обновляются
- если тип структуры изменился, лучше перекомпилировать и повторно запустить измененный код. Может быть, перезапустить программу. Эффект переопределения структуры не определен в стандартном Common Lisp.
- очень мало самоанализа: переносимый Common Lisp не говорит мне супер / субструктуры структуры простым способом. Портативный Common Lisp не говорит мне о слотах структуры.
- нет доступа к слоту через имена слотов по умолчанию
расширения
- некоторые реализации обеспечивают больший внутренний анализ во время выполнения и небольшую интеграцию в некоторые функции CLOS
Классы CLOS
CLOS был изобретен в середине / конце 80-х годов на основе двух более ранних объектных систем (Flavors и LOOPS). Это обеспечивает:
- определяющий макрос
DEFCLASS
- множественное наследование
- протоколы для создания, инициализации и т. д.
- Объекты CLOS могут быть изменены и обновлены во время выполнения на основе изменений класса (новые слоты, переопределенные слоты, удаленные слоты, измененное наследование, ...)
- Объекты CLOS могут изменять свой класс и обновляться во время выполнения
- возможен доступ через имена слотов
ограничения:
- нет принтера / ридера по умолчанию
DEFCLASS
определения не очень кратки
расширения
- более быстрый доступ к слотам благодаря дополнительным функциям реализации
- Meta-Object Protocol обеспечивает дополнительную функциональность и гибкость: самоанализ и рефлексия. Иногда предоставляются только части СС.
- доступны пользовательские расширения, особенно для реализаций с поддержкой MOP
Common Lisp
В некоторых случаях стандарт Common Lisp не говорит о том, как следует реализовывать функциональность: структуры, классы или даже что-то еще. Примерами являются потоки и условия. Обычно это хороший знак (для дополнительной гибкости), если реализация Common Lisp для них использует CLOS.
defstruct
делает больше работы для вас за кулисами, например:
- автоматически определяет доступ к слоту
- определяет читаемый
print-object
метод
Кроме того, структура доступа к слотам быстрее (хотя разница, вероятно, несущественна).
Суть в том, что, если вам не нужны функции MOPish, вы можете уйти с defsrtuct
,