Вопрос

Я пишу функцию для класса Clos, который меняет элемент списка объекта указанного класса.

У меня есть метод, который вернет обратный список, но как я могу установить список объекта в этот список? Могу ли я иметь переменную экземпляра в функции, которая хранит список, затем установите элемент на это? Или есть более простой способ?

Вот метод, как сейчас:

(defun my-reverse (lst)
    (cond ((null lst) ‘())
           (t (append (my-reverse (cdr lst)) (car lst)))))

Объект, который он проходит,-это (l my-list), а аксессуар будет тогда (My-list-ls l).

РЕДАКТИРОВАТЬ: понял, что cons не работает на 2 списка.

РЕДАКТИРОВАТЬ2: Я полагаю, что правильный код будет:

(defun my-reverse (l my-list)
        (cond ((null (my-list-ls l) ‘())
               (t (setf (my-list-ls l) (append (my-reverse (cdr (my-list-ls l)))
                                         (car (my-list-ls l)))))))
Это было полезно?

Решение

Если вы хотите изменить слот объекта, вам нужно передать этот объект самому объекту, а не только значение слота, который вы хотите изменить.

РЕДАКТИРОВАТЬ: Относительно редактирования 2 вопроса

Я предполагаю my-list Имя класса, и вы на самом деле не хотите передать его функции, верно? В этом случае вы должны заменить defun с defmethod. Анкет Кроме того, должно быть лучше изменить экземпляр только один раз, после того, как вы изменили весь список, а не на каждом шаге. Вы можете использовать внутреннюю функцию для этого:

(defmethod my-reverse ((l my-list))
  (labels ((inner (list acc)
             (if (endp list)
                 acc
                 (inner (rest list) (cons (first list) acc)))))
     (setf (my-list-ls l) (inner (my-list-ls l) ()))))

РЕДАКТИРОВАТЬ 2: Подробное объяснение

defmethod является альтернативой для defun Для определения (полиморфных) методов. Хотя, если вам не нужен полиморфизм, вы можете просто использовать (defun my-reverse (l) для первой строки.

labels для определений внутренней функции. Здесь он определяет внутреннюю функцию с именем inner с двумя параметрами list а также acc. inner это функция, которая выполняет фактическую реверсию, и это хвостовая функция, потому что реверсирование естественным образом идет с хвостовой рекурсией. (Он может построить свой результат с cons и поэтому имеет линейную сложность, тогда как ваше решение требует append и тем самым квадратичная сложность, потому что cons сам по себе постоянно, но append линейно.)

first а также rest просто альтернативные имена для car а также cdr, endp в основном это просто альтернативное название для null, с разницей, что endp сигнализирует об ошибке, если ее аргумент на самом деле не является списком.

Наконец, последние вызовы строки inner с исходным и пустым списком в качестве аргументов, и присваивает результат слоту (переменная экземпляра, как переменная экземпляра).

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