在Lisp中,我们有两个函数来定义局部函数flet
和labels
。两者基本上都是一样的,它们都具有相同的语法,它们唯一(?)的区别在于labels
本地函数可以相互引用,flet
它们不能。
有没有充分理由使用flet
?换句话说:为什么不总是使用labels
并完全摆脱flet
?
据我所知,flet
只是labels
的95%子集。我错过了什么吗?
答案 0 :(得分:8)
flet
而非labels
都不是函数。它们是特殊的,内置的操作员。
FLET
是更简单的构造。定义的局部函数仅在正文中可见。 LABELS
允许我们定义递归局部函数以及相互递归的局部函数。
CL-USER 7 > (let ((i 5))
(labels ((foo ()
(decf i) (bar))
(bar ()
(unless (zerop i)
(print i)
(foo))))
(foo)))
4
3
2
1
NIL
因此,默认情况下使用更简单的FLET
是一种很好的风格。
然后使用LABELS
表示本地函数正在使用递归。然后通过阅读LABELS
或FLET
,可以看到本地函数是否正在使用递归。
他们唯一(?)的区别在于,对于标签,本地函数可以相互引用,而flet却不能。
flet
中定义的函数也不能直接调用自身。因此,可以重新定义外部(可能是全局)函数并在定义中使用外部函数。
通常,最好不要在用户代码中使用它,因为它使代码更难理解。它可能在生成的代码中有用......有时候。