Несколько конструкторов в общем LISP - PullRequest
4 голосов
/ 02 ноября 2009

Могут ли классы иметь несколько конструкторов и / или конструкторов копирования в common-lisp? То есть - для того, чтобы создать класс для нового вектора - "vecr" для представления трехмерных векторов действительных чисел, я хотел бы определить новый класс, который можно инициализировать несколькими способами:

(vecr 1.2) ==> #(1.2 1.2 1.2)

или

(vecr 1.2 1.4 3.2) ==> #(1.2 4.3 2.5)

или

(vecr) ==> #(0.0 0.0 0.0)

Ответы [ 4 ]

7 голосов
/ 02 ноября 2009

Я не могу понять, как прокомментировать сказанное выше:

Эта функция хорошо работает для создания по умолчанию # (0,0 0,0 0,0) тип вектора. Однако (vecr 1.0) ==> # (1.0 0.0 0.0) вместо намеченного # (1,0 1,0 1.0). Я полагаю, что способ обойти это, чтобы проверить, все ли три прошло, или только один из дополнительных аргументы. - Шамстер 6 часов назад

Вы можете сделать это:

(defun vecr (&optional (x 0.0) (y x) (z y))
  (vector x y z))
4 голосов
/ 02 ноября 2009

Один простой способ заключается в следующем:

(defun vecr (&optional (x 0.0) (y 0.0 y-supplied-p) (z 0.0))
  (if y-supplied-p
      (vector x y z)
      (vector x x x)))
3 голосов
/ 02 ноября 2009

См. Функцию MAKE-ARRAY:

CL-USER 1 > (make-array 3 :initial-element 1.2)
#(1.2 1.2 1.2)

CL-USER 2 > (make-array 3 :initial-contents '(1.2 1.4 3.2))
#(1.2 1.4 3.2)

CL-USER 3 > (make-array 3)
#(NIL NIL NIL)
3 голосов
/ 02 ноября 2009

В Lisp не существует "конструкторов" или "конструкторов копирования" в том же смысле, что и в C ++.

Классы в lisp создаются с помощью make-instance и передаются по ссылке. Это означает, что копирование не происходит.

Что касается вашего вопроса, вы можете создать функцию, которая создает экземпляр класса и передает необходимые аргументы функции make-instance или иным образом инициализирует экземпляр.

В вашем случае проще всего иметь такую ​​функцию:

(defun vecr (&optional (x 0.0) (y 0.0) (z 0.0))
  (vector x y z))
...