本地“let”与本地函数

时间:2017-04-07 14:27:34

标签: emacs scope elisp

在关于Elisp中局部变量定义的another question中,两位受访者都建议let是合适的,并强调它不会将变量定义为函数的本地变量。该变量仅对let语句是本地的。

本地与let和本地函数有什么区别?是否有另一个构造可以定义函数范围的变量?

使用let语句的函数如下所示:

(defun test-search (string)
  "Searches for STRING in document.
Displays message 'Found!' or 'Not found...'. Places point after word 
when found; fixed otherwise."
  (interactive "sEnter search word: ")
  (let ((found (save-excursion
         (beginning-of-buffer)
         (search-forward string nil t nil))))
    (if found
        (progn
          (goto-char found)
          (message "Found!"))
      (message "Not found..."))))

2 个答案:

答案 0 :(得分:4)

由于let在您的示例中构成了函数的整个主体,因此您的&#34;变量是本地的,以及#34;与函数本地变量&#34; <34>无法区分。

因此,没有单独的构造来引入函数的局部变量。 let是该构造,可用于对整个函数有效的变量,也可用于对小子集有效的变量,具体取决于放置let的位置。

答案 1 :(得分:0)

  

函数的local和local之间的区别是什么?

这个问题对于解释略有开放,但我在这里解释&#34;本地功能&#34;表示不是函数的一部分的代码无法看到变量,而Emacs中的默认 <{1>}绑定不是这种情况(或者实际上对于一般的变量绑定。)

要详细了解,您需要了解动态绑定词法绑定之间的区别(并且在其他地方有很好的解释,所以您可以自己跟进)。但是,为了简要说明其差异,请考虑以下功能:

let

(defun func1 () (let ((foo 42)) (func2))) (defun func2 () (bound-and-true-p foo)) 的结果是func1的结果,而后者又取决于变量func2是否对后一个函数可见。

在默认动态绑定下,调用foo将返回func1,因为42的绑定范围是foo的持续时间,其中包含了调用到let

在词法绑定下,调用func2将返回func1,因为nil(其他方式未被声明为动态)具有foo本地的绑定,因此func1无法看到它。)

在谈论&#34;本地功能时,我实际上有点误导。关于上面的例子,因为func2绑定的范围严格地是foo形式的范围而不是函数的范围。但是,行为不仅限于let绑定,因此我们也可以使用以下示例,比较动态和词法绑定下let的结果:

(func3 42)