为何Lisp中用字符串检查符号存在时find-symbol返回:INTERNAL?
为什么
find-symbol返回:INTERNAL? 首先得明确find-symbol的核心行为:它在当前包的符号表中查找与输入字符串匹配的符号,返回两个值:
- 第一个值是找到的符号(或
nil表示未找到) - 第二个值是符号的状态:
:INTERNAL(当前包内部符号)、:EXTERNAL(当前包导出的符号)、:INHERITED(从其他包继承的符号),未找到则返回nil
你遇到的情况,本质是你传入的符号已经被Lisp自动创建了:当你写'never-used-symbol时,Lisp会检查当前包是否存在这个符号——如果不存在,就会自动在当前包创建一个内部符号(状态:INTERNAL)。所以当你调用find-symbol时,自然能找到这个已经存在的内部符号,返回对应的结果。
Lisp这么设计的原因:
- 包系统的动态便利性:自动创建未引用过的符号,避免了手动声明符号的繁琐,同时保证代码中引用的符号始终存在,减少运行时错误。
- 包的封装性需求:
:INTERNAL状态是Lisp包系统模块化的关键——内部符号只能在包内部直接访问,外部包必须通过导入才能使用,这帮助开发者构建边界清晰的模块化代码。 find-symbol的语义明确:它的职责是查找已存在于符号表中的符号,而不是检查符号是否有实际的函数/变量绑定。如果要检查符号是否被定义(有绑定),应该用fboundp(检查函数绑定)或boundp(检查变量绑定)。
正确的用法示例:
如果你想检查某个名字对应的符号是否真的“不存在”(未被创建过),可以直接用字符串调用find-symbol,不要提前引用该符号:
(find-symbol "TRULY-UNUSED-SYMBOL") ;; 返回 NIL 和 NIL,表示当前包中没有这个符号
如果要检查符号是否有实际绑定:
;; 检查是否有函数绑定 (fboundp 'never-used-symbol) ; 返回 NIL ;; 检查是否有变量绑定 (boundp 'never-used-symbol) ; 返回 NIL
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

