(defun foo (mylist)
(with-open-file (str "out.txt"
:direction :output
:if-exists :append
:if-does-not-exist :create)
(if mylist
(progn
(format str (car mylist))
(foo (cdr mylist))))))
我有两个问题。首先,我无法使用此表达式(format str (car mylist))
编写列表的元素,其次,它还会产生另一个错误,如下所示。
already points to file
"out.txt", opening the file again for :OUTPUT may produce
unexpected results
Open the file anyway
答案 0 :(得分:4)
此错误记录在the manual中。
您正在递归调用foo
,每次调用都会再次打开文件。
这可能会带来非常糟糕的后果。
您可以通过将递归调用移到with-open-file
之外来解决此问题:
(defun write-list-to-file-reopen (mylist destination)
(when mylist
(with-open-file (str destination
:direction :output
:if-exists :append
:if-does-not-exist :create)
(prin1 (pop mylist) str)
(terpri str))
(write-list-to-file-reopen mylist)))
但这效率很低,因为open
是相对昂贵的操作。
更好的解决方案是进行迭代
(defun write-list-to-file-iterate (mylist destination)
(with-open-file (str destination
:direction :output
:if-exists :append
:if-does-not-exist :create)
(dolist (el mylist)
(format str "~S~%" el))))
或者,如果需要使用递归,
(defun write-list-to-file-recursion (mylist destination)
(with-open-file (str destination
:direction :output
:if-exists :append
:if-does-not-exist :create)
(labels ((write-list (list)
(when list
(prin1 (pop list) str)
(terpri str)
(write-list list))))
(write-list mylist))))
功能format
相对来说
重量很重并且打算用于交互式漂亮的打印,
宁愿使用write
之类的简单函数。
您的问题是因为您的(format str x)
应该是(format str "~S~%" x)
:
您忘记了format string。