gpt4 book ai didi

Emacs:defun 或 defmacro 主体中的代码不能引用周围的词法变量?

转载 作者:太空宇宙 更新时间:2023-11-03 18:40:34 25 4
gpt4 key购买 nike

2013 年 5 月更新:从 GNU Emacs 24.3.1 开始,(let .. (defun..)) 字节编译正常,没有警告,字节编译代码与未编译代码的工作方式相同。只是不要忘记将文件变量 lexical-binding: t 添加到要进行字节编译的文件中。现在不需要此问题末尾的解决方法。


Lexical Binding - Emacs Lisp Manual有这段:

Note that functions like symbol-value, boundp, and set only retrieve or modify a variable's dynamic binding (i.e. the contents of its symbol's value cell). Also, the code in the body of a defun or defmacro cannot refer to surrounding lexical variables.

我不确定我是否理解了第二句话的意思。在下面应该以词法绑定(bind)模式运行的代码中,defun 主体中的代码成功引用了名称 n 的词法绑定(bind)值。

(let ((n 0))
(defun my-counter ()
(incf n)))

(my-counter) ;; 1
(my-counter) ;; 2

这句话只是说 (let .. (defun ..)) 是一种不好的做法吗?


解决方法:

;; -*- lexical-binding: t -*-

;; a way to define the counter function without byte-compile error or warning

(defvar my--counter-func
(let ((n 0))
(lambda ()
(setq n (1+ n)))))

(defun my-counter ()
(funcall my--counter-func))

;; another way to define the counter function, again without byte-compile error or warning

(fset 'my-another-counter
(let ((n 0))
(lambda ()
(setq n (1+ n)))))

下面是测试上述代码的代码:

;; run:
;; emacs -q --load path-to-the-el-file-of-this-code.el

(load "path-to-file-defining-my-counter.elc") ;; loading the ELC file to test if byte-compiled code runs as expected.

(print (my-counter)) ;; 1
(print (my-counter)) ;; 2

(print (my-another-counter)) ;; 1
(print (my-another-counter)) ;; 2

最佳答案

至少在 Emacs 24.1.1 中,代码不能很好地进行字节编译。我将以下代码保存在 foo.el 文件中,该文件使用 setq 代替 incf 以避免 cl 库:

;; -*- lexical-binding: t -*-

(let ((n 0))
(defun my-counter ()
(setq n (1+ n))))

当我尝试对其进行字节编译时 (M-x byte-compile-filefoo.el),我收到以下警告消息:

foo.el:3:1:Warning: Function my-counter will ignore its context (n)
foo.el:3:1:Warning: Unused lexical variable `n'
foo.el:5:11:Warning: reference to free variable `n'
foo.el:5:17:Warning: assignment to free variable `n'

所有消息都表明 defun 结构体中的代码不能像手册中声明的那样引用周围的词法变量 n

实际上,当我加载字节编译代码 (M-x load-filefoo.elc) 并计算 (my-counter) 表单,我收到以下错误:

Debugger entered--Lisp error: (void-variable n)
...

不幸的是,我不确定为什么代码在以源代码形式进行评估时似乎可以正常工作。

关于Emacs:defun 或 defmacro 主体中的代码不能引用周围的词法变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12026137/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com