Общий lisp: значение слота для структур defstruct

В общем, что я могу использовать для доступа к слоту структуры, используя имя / символ слота?

Что я хочу это

(defstruct point (x 0) (y 0))    
(defmacro -> (struct slot) `(slot-value ,struct ,slot))

(setf p (make-point))
(setf (slot-value p 'x) 1)
(setf (-> p 'y) 2)

Я использую clzure cl, и в clozure cl это работает. Однако, AFAIK, это нестандартное поведение (эквивалентно "неопределенному поведению" C++). Я не планирую переходить на другую реализацию CL, поэтому я должен продолжать использовать slot-value для конструкций, или есть лучший способ сделать это?

1 ответ

Решение

Обычно вы используете функции доступа со структурами.

Ваш код определяет функции доступа point-x а также point-y, Вы можете использовать их.

Вы также можете использовать SLOT-VALUE со структурами на реализациях, которые поддерживают это. Я думаю, что это большинство реализаций (GCL будет исключением). Существует программное обеспечение Lisp, которое предполагает, что SLOT-VALUE работает для структур. Я не думаю, что реализация уберет его поддержку. Это не в стандарте, потому что некоторые разработчики не хотели бы предоставлять эту функциональность в развернутых приложениях.

Так что оба пути в порядке.

Если вы хотите иметь короткие имена, используйте аксессоры:

CL-USER 109 > (defstruct (point :conc-name)
                (x 0) (y 0))
POINT

CL-USER 110 > (make-point :x 5 :y 3)
#S(POINT :X 5 :Y 3)

CL-USER 111 > (setf p1 *)
#S(POINT :X 5 :Y 3)

CL-USER 112 > (x p1)
5

CL-USER 113 > (setf p2 (make-point :x 2 :y 3))
#S(POINT :X 2 :Y 3)

CL-USER 114 > (list p1 p2)
(#S(POINT :X 5 :Y 3) #S(POINT :X 2 :Y 3))

CL-USER 115 > (mapcar 'x (list p1 p2))
(5 2)

Тогда конфликты имен между различными функциями доступа должны быть предотвращены пакетом.

Если вы хотите написать более короткую версию SLOT-VALUEЭто тоже хорошо. Написать макрос. Или напишите встроенную функцию. Конечно, почему нет?

Как я сказал, SLOT-VALUE работает со структурами в большинстве реализаций. В этом случае вас не должно волновать, что спецификация ANSI CL не определяет это. Реализации во многих отношениях расширяют спецификацию ANSI CL. Например, SLOT-VALUE работая над структурами, реализуя потоки как классы CLOS, реализуя условия как классы CLOS, обеспечивая протокол мета-объектов, ...

Другие вопросы по тегам