- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
下面的 emacs lisp 文件是关于当 Alice 在她的 init 文件中使用词法绑定(bind)的局部变量 foo
并且 Bob 将 foo
定义为全局特殊变量时会发生什么defvar
在他的 init 文件中,Alice 借用了 Bob 的部分 init 文件代码到她自己的 init 文件中,不知道 foo
会变成特殊的。
;; -*- lexical-binding: t; -*-
;; Alice init file
;; Alice defining alice-multiplier
(defun alice-multiplier-1 (foo)
(lambda (n) (* n foo)))
(defun alice-multiplier-2 (num)
(let ((foo num))
(lambda (n) (* n foo))))
;; Alice using alice-multiplier
(print
(list
:R1 (mapcar (alice-multiplier-1 10) (list 1 2 3))
:R2 (mapcar (alice-multiplier-2 10) (list 1 2 3))))
;; from Bob's code
;; ...
(defvar foo 1000)
;; ...
;; Alice using alice-multiplier
(print
(list
:R3 (mapcar (alice-multiplier-1 10) (list 1 2 3))
:R4 (mapcar (alice-multiplier-2 10) (list 1 2 3))))
输出:
(:R1 (10 20 30) :R2 (10 20 30))
(:R3 (10 20 30) :R4 (1000 2000 3000))
结果R1和R2如我所料。结果 R4 与 defvar 文档一致,尽管 Alice 可能会感到惊讶,除非她阅读 Bob 的代码。
我发现 R3 令人惊讶。为什么R3会这样?
说到 R4,Alice 可以做些什么来保护她的 foo
不被其他人变成特殊的?例如,foo
可能是她在 init 文件或她的 emacs 包之一中使用的词法局部变量,而 (defvar foo "something")
可能在某些她碰巧使用的包,或者 foo
可能是 future 版本的 Emacs 引入的新的特殊变量名称之一。 Alice 是否可以在她的文件中添加一些内容来对 Emacs 说“在这个文件中,foo 应该始终是词法的,即使来自外部的某些代码碰巧使用了同名的特殊变量”?
最佳答案
从“理论”(Scheme/Common Lisp)的角度来看,一旦您启用词法绑定(bind),出于所有实际目的 alice-multiplier-1
和 alice-multiplier- 2
相同。它们行为上的任何差异都是 Emacs Lisp 中的一个错误,应该这样报告。
已编译
如果您将代码(即 2 个 defun
和 ;; -*- lexical-binding: t; -*-
行)放入文件中, emacs-list-byte-compile-and-load
它,然后你可以通过评估这 4 种形式来测试我的说法:
(disassemble 'alice-multiplier-1)
(disassemble 'alice-multiplier-2)
(disassemble (alice-multiplier-1 10))
(disassemble (alice-multiplier-2 10))
您会看到 3 和 4 是相同的,而 1 和 2 有一条指令不同(这应该作为错误报告给 Emacs 维护者,但不会影响行为)。
请注意,没有任何反汇编提及 foo
,这意味着 defvar
将不会影响它们的行为。
一切都很好!
解释
确实,您看到的行为是不正确的; 在 defvar
之后的正确结果是
(:R1 (10000 20000 30000) :R2 (10000 20000 30000))
请report this to the emacs maintainers .
不同???
是的,defvar
确实(并且应该!)影响解释代码的行为,但不会(并且不应该!)影响已编译代码的行为。
没有办法“保护”你的 foo
不被其他人宣称为 special
- 除非在“你的”符号前加上 alice-
.
但是,如果您使用 alice-multiplier-1
定义对文件进行字节编译,编译后的文件甚至不包含 foo
,因此 的 future 声明>foo
不会影响你。
关于emacs - emacs lisp 中词法绑定(bind)和 defvar 之间的奇怪交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17400556/
Def[Type] VBA 支持从 Hell 生成的语句,似乎是为了强制执行某种 Systems Hungarian符号。 例如: Option Explicit DefBool B DefLng I
Warning Tips - GNU Emacs Lisp Reference Manual 中的第一个提示: Try to avoid compiler warnings about undefin
所以,我从 setq and defvar in lisp , http://www.cs.ucf.edu/courses/cop4020/spr2006/plsetup.html , 和 In Li
我使用的代码是这样的: (defvar my-defvar "test") (completing-read "input: " '("1" "2" my-defvar)) 然后是M-x eval-r
我看到 Practical Common Lisp使用 (defvar *db* nil) 设置一个全局变量。为同样的目的使用 setq 不是可以吗? 使用 defvar 与 setq 有什么优点/缺
我找到了一个 Similar question . 但是我不太明白那个解释。 所以我尝试使用以下示例运行 clisp: [1]> (defvar a 5) A [2]> (+ a 1)
我找到了一个 Similar question . 但是我不太明白那个解释。 所以我尝试使用以下示例运行 clisp: [1]> (defvar a 5) A [2]> (+ a 1)
我有一个移动到行尾的函数,但是当已经在行尾时,返回到之前调用它的最后一点。 这需要将最后一个点的值存储在某处。目前我将这一点存储在例如 (defvar last-point 1) 中,但我认为封装会更
我的 .emacs 中有以下设置 ... (defvar org-dir "/home/mash/read/org/") 并在...周围使用它 (setq org-directory org-dir)
在一些文档中,我发现他们说答案是 *var* 表示全局变量。 但是当我尝试时,我无法确定这一点。 FIRST-PACKAGE[27]> (defvar b 1) B FIRST-PACKA
下面的 emacs lisp 文件是关于当 Alice 在她的 init 文件中使用词法绑定(bind)的局部变量 foo 并且 Bob 将 foo 定义为全局特殊变量时会发生什么defvar 在他的
下面的函数来自Org Mode - Organize Your Life In Plain Text!它在 emacs-23.4-r1 中不起作用。但是,如果我删除 bh/organization-t
我是一名优秀的程序员,十分优秀!