2011-12-01 110 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

'(插槽值對象'插槽)',當然。 –