Noo*_*oob 3 variables loops common-lisp
我想知道是否有一种方法可以在Common Lisp loop构造中引入一些局部变量,而无需对其进行任何自动增量-就像说可以避免在循环外使用let的快捷语法一样。
Syl*_*ter 10
我们将从简单开始。如果让循环对任何累加单词执行某些操作,则只需命名绑定即可创建绑定。在这里,我进行两个绑定odds,evens由于我希望返回两个值,并且计数是“黑带循环”中所述的动词之一,当然还有CLHS循环规范:
(loop :for num :in '(1 3 5 6 3 3)
:counting (oddp num) :into odds
:counting (evenp num) :into evens
:finally (return (values odds evens)))
; ==> 5
; ==> 1
Run Code Online (Sandbox Code Playgroud)
在文档中也描述了更通用的方式是使用with子句:
(loop :with odds := 0 :and evens := 0
:for num in '(1 3 5 6 3 3)
:if (oddp num) :do (incf odds)
:else :do (incf evens)
:finally (return (values odds evens)))
; ==> 5
; ==> 1
Run Code Online (Sandbox Code Playgroud)
您已经知道了,for e = value then new-value因为它逐步执行,但是我在此处添加它以完成操作。请注意,顺序很重要:
(loop :for odds := 0 :then (if (oddp num) (1+ odds) odds)
:for evens := 0 :then (if (evenp num) (1+ evens) evens)
:for num :in '(1 3 5 6 3 3)
:finally (return (values odds evens)))
; ==> 5
; ==> 1
Run Code Online (Sandbox Code Playgroud)
最后一个例子&aux是函数中有元素。它创建let*没有let*和缩进的绑定。它通常是一个真正的选择:
(defun count-odds (list &aux (odds 0) (evens 0))
(loop :for num in list
:if (oddp num) :do (incf odds)
:else :do (incf evens))
(values odds evens))
Run Code Online (Sandbox Code Playgroud)
请注意,我们不需要使用tat,finally因为更改的绑定可以在外部使用loop
知道CL可能比我想念的还要多,但这是我使用的那些。