Вопрос

У меня есть класс узла, который имеет «элемент» слота, который содержит список с номерами и одной буквой, например:

'(1 2 3 B 4 5 6)


(defclass node ()
  ((element :reader get-element
            :writer set-element
            :initform '()
            :initarg :element
            :documentation "The element"))

Предполагается, что часть программы выполняет «элемент» слота, поменяйте букву одним из чисел и, наконец, создать новый объект узла с заменутым списком в качестве его слота «элемента». У меня уже есть функция свопа, которая принимает список и два члена этого списка и используя функцию ROTATEF, она их сводится.

Чтобы проверить, что функция Swap работала, я создал следующую часть кода, который хранится во временной переменной элементе, и сворачивает букву «B» с номером в списке:


(setf root (make-instance 'node))
(set-element '(1 2 3 b 4 5 6 7 8) root)

(SetF Temp (RET-Element Root)) (Swap Temp 'B 4)

Проблема в том, что слот «элемент» корневого объекта поменяются вместе с TEMP. Как ни странно, я попытался изменять функцию свопа, чтобы поменять, и она не модифицирует ни одно из двух.

Я не знаю, есть ли способ назначить слот к переменной или способу предотвращения происхождения выше.

Спасибо.

Это было полезно?

Решение

Reverse создает и возвращает новый список. Rotatef (как только setf, incf и тому подобное) измените место. Тебе придется copy-list или copy-tree твой element Чтобы создать новый список, который вы затем изменяете.

Другие советы

Некоторые другие замечания:

  • Вместо метода Getter и Setter используйте способ доступа. Это обычно предпочтительнее.

  • Списки создаются с помощью таких функций, как список или список копирования. Список, написанный как «(1 B 2), находится в исходном коде буквальной постоянной и не должен быть изменен. Он не определен в стандарте CL, что произойдет, если вы попытаетесь изменить буквальный список. Это может иметь нежелательные эффекты. Если у вас есть буквальный список, и вы хотите изменить его, вы должны сначала скопировать его с помощью списка копирования (или копирования) и изменить эту копию.

  • Вам также необходимо изучить разницу между неразрушающими операциями, такими как обратные и, возможно, разрушительные операции, такие как nReverse. Если вы хотите, чтобы исходный список не изменился, используйте неразрушающие операции. Природа списка или последовательности операций описана в общих гиперспеках Lisp для каждой операции.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top