【问题标题】:Define Local Variable in Common Lisp loop在 Common Lisp 循环中定义局部变量
【发布时间】:2019-09-29 09:38:17
【问题描述】:

我想知道是否有一种方法可以在 Common Lisp loop 构造中引入一些局部变量,而无需对其进行任何类型的自动增量 - 就像避免在外部使用 let 的快捷语法一样循环。

【问题讨论】:

标签: loops variables common-lisp


【解决方案1】:

我们将从最简单的开始。如果您让循环对任何累积词执行某些操作,您只需命名一个绑定并创建它。在这里,我进行了两个绑定 oddsevens,因为我希望返回两个值,并且计数是 Loop for black belts 和当然 CLHS loop specification 中描述的动词之一:

(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

文档中也描述了更通用的方法是使用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

您已经知道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

作为最后一个例子,我们在函数中有&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))

请注意,我们不需要使用 finally,因为更改后的绑定在 loop 之外可用

知道 CL 可能还有一些我错过了,但这些是我使用的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多