19.6 Функции-конструкторы с позиционными аргументами

Если параметр :constructor указан: так (:constructor name arglist), тогда вместо создания конструктора с именованными параметрами, defstruct определит конструктор с позиционными аргументами. Форма arglist используется для описания того, какие аргументы будет принимать конструктор. В простейшем случае что-то вроде (:constructor make-foo (a b c)) определяет функцию make-foo с тремя аргументами, которые используются для инициализации слотов a, b и c.

Кроме того в списке аргументов могут использоваться &optional, &rest и &aux. Они работают так, как и ожидается, но есть несколько тонкостей требующих объяснения. Рассмотрим пример:

(:constructor create-foo
        (a &optional b (c ’sea) &rest d &aux e (f ’eff)))

Эта конструкция определяет конструктор create-foo для использования с одним или более аргументами. Первый аргумент используется для инициализации слота a. Если второй параметр не указан, используется значение (если указано) по-умолчанию из тела defstruct. Третий аргумент используется для инициализации слота c. Если третий параметр не указан, тогда используется символ sea. Все параметры после третьего собираются в список и используются для инициализации слота d. Если указано три и более параметров, тогда в слот d помещается значение nil. Слот e не инициализируется. Его первоначальное значение не определено. Наконец, слот f инициализируется символом eff.

Действия со слотами b и e выбраны не случайно, а для того чтобы показать все возможные случаи использования аргументов. Следует отметить, что &aux (вспомогательные) «переменные» могут использоваться для перекрытия форм инициализации из тела defstruct.

Следуя этому определению можно записать

(create-foo 1 2)

вместо

(make-foo :a 1 :b 2)

и, конечно, create-foo предоставляет инициализацию отличную от make-foo.

Использовать :constructor можно более одного раза. Таким образом вы можете определить несколько различных функций-конструкторов с различными аргументами.