根据symbol-value的说明,当开启静态作用域时,只能取到全局环境下symbol的值,而不是当前作用域下symbol的值
但是
;; -*- lexical-binding: t; -*-
(defvar v "global")
(defun test ()
(let ((v "let"))
(symbol-value (intern "v"))))
(test) ;let
(defun test-1 ()
(let ((a "let"))
(symbol-value (intern "a"))))
(test-1) ;(void-variable a)
感觉整个人都不好了,不知道是不是Emacs25的BUG?Emacs24有没有这个呢?
确实很奇怪。 。。 感觉第二个测试例的输出结果无法理解。。
第一个测试的结果也跟doc-string说明中的不一样…
可能是由于 defvar
比较特殊,你可以把它换成 setq
试一试:
In Emacs 24, defvar creates things called special variables. Special variables are dynamically scoped variables that will be bound dynamically even in lexically scoped functions.
引用来源:
果然是这样,换成setq第一个例子就是返回"global"了
现在还有个问题,在第二个例子中,会直接报错. 那么有没有什么方法是可以让它返回"let"呢?
换句话说,希望能够做到:
(defun test-1 ()
(let ((a "let"))
(some-function-like-symbol-value (intern "a"))))
(test-1) ;希望它能返回"let"
我觉得并没有什么好办法。。。
symbol-value
(eval
, set
类似) 只能处理 dynamic scoping 的变量,所以
- 要么不要开启 lexical-binding
- 要么用
defvar
定义成 dynamic scoping 的 special variable,就像你的第一个 test
函数一样