19.1 Введение в структуры

Функциональность структур воплощена в макросе defstruct, который позволяет пользователю создавать и использовать сгруппированные типы данных с именованными элементами. Она похожа на функциональность «структур (structures)» в PL/I или «записей (records)» в Pascal’е.

В качестве примера, предположим, что вы пишете программу на Lisp’е, которая управляет космическими кораблями в двухмерном пространстве. Вам необходимо представить космический корабль как некоторого вида Lisp’овый объект. Интересующими свойствами корабля являются: его позиция (представленная как x и y координаты), скорость (представленная как отрезки по осям x и y) и масса.

Таким образом, корабль может быть представлен как запись структуры с пятью компонентами: позиция-x, позиция-y, скорость-x, скорость-y и масса. Эта структура может быть реализована как Lisp’овый объект несколькими способами. Она может быть списком из пяти элементов; позиция-x будет car элементом, позиция-y будет cadr, и так далее. Подобным образом структура может быть вектором из пяти элементов: позиция-x будет 0-ым элементом, позиция-y будет 1-ым, и так далее. Проблема данных представлений состоит в том, что компоненты занимают совершенно случайные позиции и их сложно запомнить. Кто-нибудь увидев где-то в коде строки (cadddr ship1) или (aref ship1 3), обнаружит сложность в определении того, что это производится доступ к компоненту скорости-y структуры ship1. Более того, если представление корабля должно быть изменено, то будет очень сложно найти все места в коде для изменения в соответствие с новым представлением (не все появления cadddr означают доступ к скорости-y корабля).

Лучше было бы, если бы записи структур имели имена. Можно было бы написать что-то вроде (ship-y-velocity ship1) вместо (cadddr ship1). Кроме того было бы неплохо иметь более информативную запись для создания структур, чем эта:

(list 0 0 0 0 0)

Несомненно, хочется, чтобы ship был новым типом данных, как и любой другой тип Lisp’овых данных, чтобы, например, осуществить проверку с помощью typep. defstruct предоставляет вам все, что необходимо.

defstruct является макросом, который определяет структуру. Например, для космического корабля, можно определить структуру так:

(defstruct ship
  x-position
  y-position
  x-velocity
  y-velocity
  mass)

Запись декларирует, что каждый объект ship является объектом с пятью именованными компонентами. Вычисление этой формы делает несколько вещей.

Этот простой пример отображает мощь и удобство defstruct для представления записей структур. defstruct имеет много других возможностей для специализированных целей.