Lisp 中的实例变量?
我正在为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果要修改对象的槽,则需要将该对象本身传递给函数,而不仅仅是要更改的槽的值。
编辑:关于问题的编辑2,
我假设 my-list 是类的名称,并且您实际上并不希望将其传递给函数,对吗?在这种情况下,您应该用
defmethod
替换defun
。另外,最好在反转整个列表后仅更改实例一次,而不是每一步都更改实例。您可以为此使用内部函数:编辑 2:详细说明
defmethod
是定义(多态)方法的defun
的替代方案。不过,如果您不需要多态性,则可以在第一行使用(defun my-reverse (l)
。labels
用于内部函数定义。在这里,它定义了一个名为inner
的内部函数,带有两个参数list
和acc
是执行以下操作的函数。实际的反转,它是尾递归函数,因为尾递归可以自然地进行反转(它可以使用 cons 构建其结果,因此具有线性复杂度,而您的解决方案需要附加,因此具有二次复杂度。 ,因为cons
本身是常量,但append
是线性的。)first
和rest
只是 <代码>汽车和<代码>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 thedefun
with adefmethod
. 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:EDIT 2: detailed explanation
defmethod
is the alternative todefun
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 namedinner
with the two parameterslist
andacc
.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 withcons
and is therefore of linear complexity, whereas your solution needsappend
and thereby is of quadratic complexity, becausecons
itself is constant, butappend
is linear.)first
andrest
are just alternate names forcar
andcdr
,endp
is mostly just an alternate name fornull
, with the difference thatendp
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).