Elisp 延长变量生命周期
Elisp extend variable lifetime
我有一个循环,我在每次迭代中创建一个局部变量。然后我声明一个 lambda,它在将来某个时候使用局部变量。
(dolist (entry (read-lines "~/.emacs-projects"))
(let ((project (car (json-read-from-string entry)))) ;; <---- I NEED THIS ONE
(widget-create 'link
:button-prefix ""
:button-suffix ""
:action (lambda (wid &rest ignore) (load-project project)) ;; HERE
(format "%s : %s\n" (car project) (cdr project)))))
在上面的代码中,我创建了 project
,当 :action
触发时,我想使用 project
作为另一个函数的参数。目前,当 lambda 为 运行 时,我得到 Symbol’s value as variable is void: project
,这让我认为外部范围未保留。
如何延长 project
的生命周期以便我可以在 lambda 中访问它?
要么使用词法范围(非nil
variable lexical-binding
),要么使用列表 lambda 形式,用 project
的值代替变量本身:
(dolist (entry (read-lines "~/.emacs-projects"))
(let ((project (car (json-read-from-string entry)))) ;; <---- I NEED THIS ONE
(widget-create 'link
:button-prefix ""
:button-suffix ""
:action `(lambda (wid &rest ignore) (load-project ',project)) ;; HERE
(format "%s : %s\n" (car project) (cdr project)))))
如果你的动作函数并不真的需要project
作为变量,而只是需要它的值,那么你可以直接替换值,如图所示。
但在那种情况下,您的 lambda 形式将是一个列表(其汽车是 lambda
,等等),因此在评估之前它不会被识别为函数。特别是,字节编译器只会将其视为一个列表,而不是一个函数。
您想使用 Emacs Lisp 的词法范围风格,这是添加到 Emacs-24 的主要创新之一。为此,只需在 Elisp 文件的第一行某处(通常在注释中)添加以下内容:
-*- lexical-binding:t -*-
希望在将来的某个时候,旧的动态范围方言将不再是默认方言。
我有一个循环,我在每次迭代中创建一个局部变量。然后我声明一个 lambda,它在将来某个时候使用局部变量。
(dolist (entry (read-lines "~/.emacs-projects"))
(let ((project (car (json-read-from-string entry)))) ;; <---- I NEED THIS ONE
(widget-create 'link
:button-prefix ""
:button-suffix ""
:action (lambda (wid &rest ignore) (load-project project)) ;; HERE
(format "%s : %s\n" (car project) (cdr project)))))
在上面的代码中,我创建了 project
,当 :action
触发时,我想使用 project
作为另一个函数的参数。目前,当 lambda 为 运行 时,我得到 Symbol’s value as variable is void: project
,这让我认为外部范围未保留。
如何延长 project
的生命周期以便我可以在 lambda 中访问它?
要么使用词法范围(非nil
variable lexical-binding
),要么使用列表 lambda 形式,用 project
的值代替变量本身:
(dolist (entry (read-lines "~/.emacs-projects"))
(let ((project (car (json-read-from-string entry)))) ;; <---- I NEED THIS ONE
(widget-create 'link
:button-prefix ""
:button-suffix ""
:action `(lambda (wid &rest ignore) (load-project ',project)) ;; HERE
(format "%s : %s\n" (car project) (cdr project)))))
如果你的动作函数并不真的需要project
作为变量,而只是需要它的值,那么你可以直接替换值,如图所示。
但在那种情况下,您的 lambda 形式将是一个列表(其汽车是 lambda
,等等),因此在评估之前它不会被识别为函数。特别是,字节编译器只会将其视为一个列表,而不是一个函数。
您想使用 Emacs Lisp 的词法范围风格,这是添加到 Emacs-24 的主要创新之一。为此,只需在 Elisp 文件的第一行某处(通常在注释中)添加以下内容:
-*- lexical-binding:t -*-
希望在将来的某个时候,旧的动态范围方言将不再是默认方言。