只需綁定一個變量與值的副本。例如:
(let ((i i))
(lambda() i))
這實際上是用的迭代結構的一項重要技術,因爲像
(loop for i from 1 to 10
collecting (lambda() i))
可以在相同的變量返回10封,所以寫有必要:
(loop for i from 1 to 10
collecting (let ((i i)) (lambda() i)))
如果你真的只需要一個返回值的函數,你也可以使用constantly(但我期望真實的用例更復雜):
(loop for i from 1 to 10
collecting (constantly i))
迭代形式的歧義實際上是由標準指定的,在某些情況下。例如,對於dotimes,dolist
這是實現相關dotimes是否建立VAR的一個新的綁定在每次迭代或者是否建立之初的VAR綁定一次,然後分配給它的任何後續的迭代。
更原始do,然而,實際上規定了有一組綁定的形式,和(強調),它們在每次迭代更新:
在每次的開始除第一次迭代外,變量更新如下。…
這種不明確性給實現帶來了更多的靈活性。
(defmacro dolist ((var list &optional result) &body body)
`(progn (mapcar #'(lambda (,var)
,@(ex:body-declarations body)
(tagbody
,@(ex:body-tags-and-statements body)))
,list)
(let ((,var nil))
,result)))
(defmacro dolist ((var list &optional result) &body body)
(let ((l (gensym (string '#:list-))))
`(do* ((,l ,list (rest ,l))
(,var (first ,l) (first ,l)))
((endp ,l) ,result)
,@body)))
我Dolist,例如可以用下面的一種來定義建議閱讀一下關於「LET」。 – 2014-11-03 01:04:51