如何修改函数内部的列表


(defun list-parser (list count)
...);;this function reads items by count from list and do some process to them.
;;i.e.convert items read from code to char, or to other things and then return it. 
;;Also, the items in list should be consumed, globally. 
(defmethod foo ((obj objtype-2) data-list)
(setf (slot-1 obj) (read-list data-list 1))
obj)
(defmethod foo ((obj objtype-1) data-list)
(setf (slot-1 obj) (read-list data-list 1)
(print data-list)
(slot-2 obj) (read-list data-list 2)
(print data-list)
(slot-3 obj) (foo (make-instance 'objtype-2) data-list)
(print data-list)
(slot-4 obj) (read-list data-list 3))
obj)

如何让它像这样工作:(read-list在某些方面就像read-byte一样工作:

1。返回一个已读(此处已解析)的值

2。更改流的位置(这里是列表))。

(let ((obj)
(data))
(setf data '(1 2 3 4 5 6 7 8)
obj (foo (make-instance 'objtype-1) data))
(print data))
>>(2 3 4 5 6 7 8)
>>(4 5 6 7 8)
>>(5 6 7 8)
>>(8)

或者更确切地说,你如何处理这种任务?是否将列表转换为其他类型?

我不太确定你是什么之后,但这里是一个函数,创建一个'列表阅读器'对象(只是一个函数)。列表阅读器可以让你读取列表的块,将其视为流。

(defun make-list-reader (l)
;; Make a list reader which, when called, returns three values: a
;; chunk of list, the length of tha chunk (which may be less than
;; how much was asked for) and the remaining length.  The chunk is
;; allowed to share with L
(let ((lt l)
(len (length l)))
(lambda (&optional (n 1))
(cond
((zerop len)
(values nil 0 0))
((< len n)
(values lt len 0))
(t
(let ((it (subseq lt 0 n)))
(setf lt (nthcdr n lt)
len (- len n))
(values it n len)))))))
(defun read-from-list-reader (r &optional (n 1))
;; Read from a list reader (see above for values)
(funcall r n))

现在:

(defvar *l* (make-list-reader '(1 2 3)))
*l*
> (read-from-list-reader *l* 1)
(1)
1
2
> (read-from-list-reader *l* 2)
(2 3)
2
0
> (read-from-list-reader *l* 10)
nil
0
0

你真正不能做的是写一个函数(当然不是一个函数,因为它修改了它的参数),它像这样工作,同时修改它的参数列表。所以你可以写一个这样的函数:

> (let ((l (list 1 2)))
(values (read-from-list l)
l))
(1)
(2)

,它通过修改l的第一个cons的carcdr来工作。但这不能工作,当没有更多的读取:l是一个cons和nil不是一个cons,所以你不能让lnil与一个函数。

但是在任何情况下,这样的函数都只是一堆粗心大意的陷阱,通常是可怕的:例如,你的例子可能涉及修改字面量,这是不合法的。

最新更新