Общий 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, обеспечивая протокол мета-объектов, ...