我在Common lisp中学习了块并做了这个例子来看看块和return-from命令是如何工作的:
(block b1
(print 1)
(print 2)
(print 3)
(block b2
(print 4)
(print 5)
(return-from b1)
(print 6)
)
(print 7))
它将按预期打印1,2,3,4和5。将返回值更改为(从b2返回)它将打印1,2,3,4,5和7,正如人们所期望的那样。
然后我尝试将其转换为函数并在返回来自paremetrize标签:
(defun test-block (arg) (block b1
(print 1)
(print 2)
(print 3)
(block b2
(print 4)
(print 5)
(return-from (eval arg))
(print 6)
)
(print 7)))
并使用(test-block' b1)查看它是否有效,但它没有。有没有办法在没有条件的情况下做到这一点?
答案 0 :(得分:4)
使用条件类似CASE选择要从
返回的块建议的方法是使用case
或类似方法。 Common Lisp不支持块的计算返回。它也不支持计算go
s。
使用case
条件表达式:
(defun test-block (arg)
(block b1
(print 1)
(print 2)
(print 3)
(block b2
(print 4)
(print 5)
(case arg
(b1 (return-from b1))
(b2 (return-from b2)))
(print 6))
(print 7)))
无法从名称中计算词汇go标签,返回块或本地函数
CLTL2谈到go
构造的限制:
兼容性说明:``计算机去''不支持MacLisp的功能。计算go的语法是特殊的,Lisp Machine Lisp,NIL(Lisp的新实现)或Interlisp不支持该功能。无论如何,计算出的go在MacLisp中很少被使用,并且通过使用case子语句(每个子句执行(非计算)go)来轻松模拟而不会降低效率。
由于go
和return-from
等功能是词法范围的构造,因此不支持计算目标。 Common Lisp无法在运行时访问词法环境并查询它们。例如,本地功能也不支持这种功能。在一些词汇环境中,人们不能取名并要求使用该名称的函数对象。
动态替代方案:CATCH和THROW
通常效率较低且动态范围较广的替代方案是catch
和throw
。在那里计算标签。