2

据我了解,标签的使用是定义一个与 flet 相同但范围更大的本地函数。那是对的吗。我将提供一个例子:

(defun nested-average (tree)
  ;labels are the same as flet but with higher scope, define local functions
  (labels ((%nested-average
                ;arguments for the function
                (branch sum visited)                
                (cond
                 ((consp branch)
                      (multiple-value-call
                      ;calls the previous function with reference to the label
                       #'%nested-average (rest branch)
                       (%nested-average (first branch) sum visited)))

                   ;is branch a number
                 ((numberp branch)
                    (values (+ sum branch) (1+ visited)))
                  ;otherwise
                 (t 
                 (values sum visited))
                 )
            )
           )
            (multiple-value-call #'/ (%nested-average tree 0 0))
    )
)
    ;(nested-average ' (10 ((30 1) 20) (8 (5 (50 7)) 9) 40))
4

1 回答 1

3

在 Hyperspec 中:labels 等价于 flet,只是为标签定义的函数名称的范围包括函数定义本身以及主体。

这实际上意味着标签允许您编写递归函数。例如:

(defun fact (n)
  (labels ((rec (x)
             (if (< x 1) 
                 1
                 (* x (rec (- x 1))))))
    (rec n)))

这个函数工作正常,但是用 flet 编写的相同函数会导致错误,因为符号 rec 不会绑定在函数定义中。如果出于同样的原因使用 flet 编写,您提供的示例函数会导致错误。

于 2012-11-06T19:40:08.490 回答