Answers:
在Elisp代码中,当您想要获取符号的值时,即在将其视为变量时,需要它的值时,就需要它。
请记住,Elisp符号具有几个特征/特征:
symbol-name
给出)symbol-value
给出)symbol-function
给出)时,它可能会命名一个函数symbol-plist
给出了)将符号视为具有各种属性的对象。
symbol-value
始终返回符号的动态绑定。您无法通过这种方式获取词汇值。
C-h i g
(elisp) Symbol Components
RET
有关这些各种符号单元格/组件的文档。
(setq lexical-binding t) (let ((v 42)) (message "lex: %S, val: %S" lexical-binding (symbol-value 'v)))
。但是,是的,这就是它在(elisp)上所说的Lexical Binding
:“ 像symbol-value
,boundp'
和这样的函数,set'
仅检索或修改变量的动态绑定(即,其符号值单元格的内容) ”。但是,在上什么也没有说Symbol Components
。
(Doh,@ Drew已经提出了一些后续措施。无论如何,这是一些其他细节。)
正如符号组件的手册页所述,每个符号有四个组件(单元格):其打印名称单元格,其值单元格,其功能定义以及其属性列表。值单元格或功能单元格可能为空,而属性列表可能为nil。
手册还指出:
因为每个符号都有单独的值和函数单元格,所以变量名和函数名不会冲突。
这就是为什么可以这样,例如:
(setq test "kittens")
(defun test ()
(message "puppies"))
(symbol-value 'test) ; => "kittens"
(symbol-function 'test) ; => (lambda nil (message "puppies"))
这里有一些历史参考(当所描述的事件发生时,我还没有出生,所以也许有更多知识渊博的人会纠正我。所有这些都来自于阅读旧文章和一些书)。
放弃了免责声明后,似乎在Fortran与Lisp时代,“符号”是一个流行语,因为今天是“面向对象”。即,程序通常被视为只是巨大的数学公式,在这些公式中最终将插入数字,并且数字的占位符并不重要。一旦程序被运行,编译或解释,程序中包含的所有符号信息都将消失。Lisp的新颖之处在于,它甚至允许符号在运行,编译或解释后仍保留在程序中。这启发了诸如“符号代数”之类的术语(如在纸/黑板上对代数公式的操纵,而不是直接计算)。为了支持此(和其他象征性事物),应为标志配备名称和一些属性。从非符号的角度来看,有人可能会说“符号只是命名为指针”,虽然这不是事实,但如果更多的话,它们更多是指向结构的指针,但出于实际目的,符号是左侧的指示符可变值对的另一端。这也使得可以看到symbol-value
在非符号语言中用作指针取消引用。
现代Lisps的不同之处在于,一个符号可以关联多少值(假设您有一个具有多个内存堆栈/堆的非符号语言,您可以想象这样一种情况:在不同堆栈/上下文中解释时,同一指针具有含义)堆)。因此,Lisp2语言(Emacs Lisp是这样的一种语言)具有用于函数和变量的单独存储,这就是为什么还有a的原因symbol-function
,它“取消引用指向函数存储的指针”。Scheme没有这个特殊的存储,而Clojure AFAIK也没有symbol-plist
。