Как я могу сделать так, чтобы конструктор структуры оценивался последовательно в Common Lisp? - PullRequest
5 голосов
/ 15 сентября 2011

Я хотел бы сделать что-то похожее на это:

(defstruct person
  real-name
  (fake-name real-name)) ;if fake-name not supplied, default to real-name

Однако Common Lisp говорит The variable REAL-NAME is unbound. Так как я могу заставить конструктор последовательно оценивать свои аргументы (как я могу с аргументами-ключевыми словами функции) или как еще мне лучше это делать?

1 Ответ

10 голосов
/ 15 сентября 2011

Один из способов:

(defstruct (person
             (:constructor make-person (&key real-name
                                             (fake-name real-name))))
  real-name
  fake-name)

Вы можете существенно адаптировать функцию конструктора к вашим потребностям, включая

  • с именем, отличным от make-xxx
  • когда Лисп генерирует конструктор "по порядку аргументов" (BOA) вместо основанного на ключевых словах

Рассмотрим

(defstruct (person 
             (:constructor make-person (real-name
                                        &optional (fake-name real-name))))
    real-name
    fake-name)

Вы даже можете инициализировать созданные поля, используя ключевое слово &aux lambda-list:

(defstruct (person
             (:constructor make-person (real-name
                                        &aux (fake-name (format nil
                                                                "fake-of-~A"
                                                                real-name)))))
    real-name
    fake-name)
...