如何在 do 循环内绑定从函数返回的多个值? 下面的显然是非常错误的,但是这样的事情可能吗?
(do (((x y z) (3-val-fn) (3-val-fn)))
((equal y 'some-val) y)
(values x y z))
或者也许有一种方法可以使用多值绑定来做到这一点?
标准迭代结构中的多个值并不真正支持。
使用 LOOP 你的代码片段可能看起来像这样:
(loop with x and y and z
do (setf (values x y z) (3-val-fn))
while (equal y 'some-val)
finally (return y)
do ...)
如果我经常需要类似的东西,我可能会定义一个
do-mv
宏,它将扩展到上面的代码中。代码如下所示:
(do-mv ((x y z) (3-val-fn))
((equal y 'some-val) y)
...)
使用上面的优点是它不会在每次迭代期间从多个值创建列表。从多个值创建列表有点违背了多个值的目的,多个值返回多个值并允许以有效的方式实现它。
怎么样?:
(loop for (x y z) = (multiple-value-list (3-val-fn))
...etc)
我会提供更多,但无法理解 do-loop。
(有点)可以用
do*
:
(defun foo (n)
(do* ((n n (1- n))
(values (multiple-value-list (truncate 17 n))
(multiple-value-list (truncate 17 n)))
(result (first values) (first values))
(remainder (second values) (second values)))
((< n 3) nil)
(format t "Result: ~d, remainder: ~d, n: ~d~%" result remainder n)))
这里我们首先将多值函数结果转换为列表,将其绑定到变量,然后手动解构它。但它很难阅读,应该避免,除非
do
系列迭代结构确实比使用 loop
更好。