2011-12-01 86 views
-1

我正在写为反转说类的一个对象的列表元素的CLOS类的功能。Lisp中的实例变量?

我有一个方法将返回反向列表,但我如何使它将对象的列表设置为该列表?我可以在存储列表的函数中使用实例变量,然后将该元素设置为该变量?还是有更简单的方法?

这里的方法,因为它现在是:

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

它传递的对象是(L我的列表),然后访问将是(我的列表-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))))))) 

回答

1

如果要修改对象的插槽,你需要的是对象本身传递给你的函数,而不仅仅是插槽的价值,你想改变。

编辑:关于这个问题

的EDIT2我假设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与两个参数listacc内部函数。 inner是不实际的倒车功能,并且由于倒车用尾递归自然去这是一个尾递归函数。 (它可以与cons构建其结果,因此是线性复杂性,而你的解决方案需要append并由此是二次的复杂性,因为cons本身是恒定的,但append是线性的。)

firstrest只是替代名称对于carcdr,endp大多只是null的备用名称,不同之处在于,如果endp的参数实际上不是列表,则会发出错误信号。

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

+0

这就是我通过设置参数(l my-list)所做的事情。示例代码是用于使用任何列表进行处理,我的问题是使函数将结果保存在my-list l的列表元素中。 – Portaljacker

+1

当前示例代码中的函数正在接收一个列表,而不是CLOS对象。要么你误解你在做什么,要么你的示例代码与你的问题根本不相关。一般来说,关于你的问题,作为作者的每个访问者函数都是一个SETF可能的地方。如果没有这样的访问器,'(slot-value slot)'也是一个SETF能够的地方。 –

+0

'(插槽值对象'插槽)',当然。 –