Lisp 中的实例变量?

发布于 2024-12-19 02:25:15 字数 649 浏览 3 评论 0原文

我正在为 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 个列表。

Edit2:我认为正确的代码是:

(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)))))))

I'm writing a function for a CLOS class that reverses the list element of an object of said class.

I have a method that will return the reverse list, but how do I make it set the object's list to that list? Can I have a instance variable in the function that stores the list then set the element to that? Or is there an easier way?

Here's the method as it is now:

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

The object it is passed is (l my-list) and the accessor would then be (my-list-ls l).

Edit: Realized that cons doesn't work on 2 lists.

Edit2: What I assume the right code would be:

(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)))))))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

与风相奔跑 2024-12-26 02:25:15

如果要修改对象的槽,则需要将该对象本身传递给函数,而不仅仅是要更改的槽的值。

编辑:关于问题的编辑2,

我假设 my-list 是类的名称,并且您实际上并不希望将其传递给函数,对吗?在这种情况下,您应该用 defmethod 替换 defun。另外,最好在反转整个列表后仅更改实例一次,而不是每一步都更改实例。您可以为此使用内部函数:

(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 的内部函数,带有两个参数 listacc 是执行以下操作的函数。实际的反转,它是尾递归函数,因为尾递归可以自然地进行反转(它可以使用 cons 构建其结果,因此具有线性复杂度,而您的解决方案需要附加,因此具有二次复杂度。 ,因为 cons 本身是常量,但 append 是线性的。)

firstrest 只是 <代码>汽车和<代码>cdr, endp 主要只是 null 的替代名称,不同之处在于,如果 endp 的参数实际上不是列表,则会发出错误信号。

最后,最后一行使用原始列表和空列表作为参数调用 inner ,并将结果分配给槽(也称为实例变量)。

If you want to modify an object's slot, you need to pass that object itself to your function, not just the value of the slot you want to change.

EDIT: regarding the edit2 of the question

I assume my-list is the name of the class, and you don't actually want to pass it to the function, right? In that case, you should substitute the defun with a defmethod. Also, it should be better to change the instance only once, after you reversed the whole list, instead of at each step. You could use an inner function for that:

(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) ()))))

EDIT 2: detailed explanation

defmethod is the alternative to defun for defining (polymorphic) methods. Though, if you don't need polymorphism, you could just use (defun my-reverse (l) for the first line.

labels is for inner function definitions. Here, it defines an inner function named inner with the two parameters list and acc. inner is the function that does the actual reversing, and it's a tail-recursive function because reversing goes naturally with tail-recursion. (It can build its result with cons and is therefore of linear complexity, whereas your solution needs append and thereby is of quadratic complexity, because cons itself is constant, but append is linear.)

first and rest are just alternate names for car and cdr, endp is mostly just an alternate name for null, with the difference that endp will signal an error if its argument isn't actually a list.

Finally, the last line calls inner with the original and an empty list as arguments, and assigns the result to the slot (aka instance variable).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文