之前都没注意到有 make-symbol
这个函数。看了一下它的定义,跟 intern
确实不太一样:
-
intern
首先会根据参数STRING
从表中查找现存的符号,如果不存在则创建。所以两次(intern "foo")
返回的是同一个 symbol;而两次(make-symbol "foo")
返回的是不同的 symbol,所以eq
比较结果为 nil。 -
intern
返回的 symbol,有对应的 value;而make-symbol
返回的 symbol,其对应的 value 是 void。
源代码可以看出两个函数到底干了啥:
Elisp | C
-----------------|----------------------------------------
(intern STRING) | ...
| tem = oblookup(obarray, ...STRING, ...);
| ...
| return tem;
Elisp | C
--------------------|----------------------------------------
(make-symbol NAME) | ...
| init_symbol (val, name);
| .--^-------------------------------------.
| | struct Lisp_Symbol *p = XSYMBOL (val); |
| | ... |
| | set_symbol_name (val, name); |
| | ... |
| | SET_SYMBOL_VAL (p, Qunbound); |
| '----------------------------------------'
| ...
| return val;