当我问到如何Get numbers for the lottery时,我被赋予了提示来创建一个混合列表的函数。所以我试着这样做,我甚至让它发挥作用。
我目前的实现如下:
(defun shuffle (list)
(let ((len (length list)))
(loop repeat len
do
(rotatef
(nth (random len) list)
(nth (random len) list))
finally
return list)))
好消息是它有效:
(shuffle '(1 2 3 4 5 6))
;; => (3 1 4 2 6 5)
坏消息是我收到错误消息:
警告:LOOP:紧跟在FINALLY之后的循环关键字:CLtL2允许,ANSI CL禁止。
不幸的是我不明白。为什么告诉我loop
之后会立即显示finally
?而且,实际导致此问题的代码有什么问题?
有没有更好的方法来制定这个?
答案 0 :(得分:6)
警告:LOOP:紧跟在FINALLY之后的循环关键字:CLtL2允许,ANSI CL禁止。
这意味着RETURN
是一个循环关键字,根据ANSI CL标准,finally
之后不允许这样做。
如果我们想要从LOOP
返回,我们需要使用return
宏:
(loop ...
finally (return list))
这实际上是一个常见的错误。自ANSI CL标准以来,不再允许finally return <expr>
。这也是不使用CLtL2(Common Lisp the Language,2nd Edition)作为参考的原因。 CL Hyperspec是更好的参考。