关于make-symbol和assq,我在这里错过了什么?

ecm*_*aut 5 elisp

我正在尝试生成一个let块接受局部变量定义的相同结构但是我遇到了一个墙:给定此parse函数:

(defun parse (string)
  (mapcar (lambda (line)
            (let* ((k_v (split-string line "="))
                   (key (make-symbol (first k_v)))
                   (val (second k_v)))
              (list key val)))
          (split-string string "\n" t)))
Run Code Online (Sandbox Code Playgroud)

我在lisp-interaction-mode中看到了所寻求的输出:

(setq alist (parse "foo=bar\nbaz=quux\n"))
((foo "bar") (baz "quux"))
Run Code Online (Sandbox Code Playgroud)

鉴于…

(assq 'foo '((foo "bar") (baz "quux")))
(foo "bar")
Run Code Online (Sandbox Code Playgroud)

......我希望下面会得到相同的结果 - 我错过了什么?

(assq 'foo alist)
nil
Run Code Online (Sandbox Code Playgroud)

虽然如果Emacs版本很重要,我会感到惊讶,但我已经在OSX上的Emacs 24.2(9.0)中对此进行了测试.

mic*_*ica 6

make-symbol文档:

(make-symbol NAME)

Return a newly allocated uninterned symbol whose name is NAME.
Its value and function definition are void, and its property list is nil.
Run Code Online (Sandbox Code Playgroud)

assq正在将实习符号foo与一些恰好被命名的随机未分隔符号进行比较foo,这当然会失败,因为它们不是同一个符号.

使用intern而不是make-symbol(如下所示)可以解决您的问题.

(intern STRING &optional OBARRAY)

Return the canonical symbol whose name is STRING.
If there is none, one is created by this function and returned.
A second optional argument specifies the obarray to use;
it defaults to the value of `obarray'.
Run Code Online (Sandbox Code Playgroud)
(defun parse (string)
  (mapcar (lambda (line)
            (let* ((k_v (split-string line "="))
                   (key (intern (first k_v))) ; change here
               (val (second k_v)))
              (list key val)))
          (split-string string "\n" t)))
Run Code Online (Sandbox Code Playgroud)

(intern "foo")返回实习符号foo,该符号将被添加到您的列表中,从而(assq 'foo alist)可以正常工作.

(在Win7上测试我的Emacs 24.2.1.)