6.2 局部函数 (Local Functions)
通过 defun
或 symbol-function
搭配 setf
定义的函数是全局函数。你可以像存取全局变量那样,在任何地方存取它们。定义局部函数也是有可能的,局部函数和局部变量一样,只在某些上下文内可以访问。
局部函数可以使用 labels
来定义,它是一种像是给函数使用的 let
。它的第一个实参是一个新局部函数的定义列表,而不是一个变量规格说明的列表。列表中的元素为如下形式:
(name parameters . body)
而 labels
表达式剩余的部份,调用 name
就等于调用 (lambda parameters . body)
。
> (labels ((add10 (x) (+ x 10))
(consa (x) (cons 'a x)))
(consa (add10 3)))
(A . 13)
labels
与 let
的类比在一个方面上被打破了。由 labels
表达式所定义的局部函数,可以被其他任何在此定义的函数引用,包括自己。所以这样定义一个递归的局部函数是可能的:
> (labels ((len (lst)
(if (null lst)
0
(+ (len (cdr lst)) 1))))
(len '(a b c)))
3
5.2 节展示了 let
表达式如何被理解成函数调用。 do
表达式同样可以被解释成调用递归函数。这样形式的 do
:
(do ((x a (b x))
(y c (d y)))
((test x y) (z x y))
(f x y))
等同于
(labels ((rec (x y)
(cond ((test x y)
(z x y))
(t
(f x y)
(rec (b x) (d y))))))
(rec a c))
这个模型可以用来解决,任何你对于 do
行为仍有疑惑的问题。
当前内容版权归 readthedocs 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 readthedocs .