Emacs Lisp:在关联列表中评估变量

29

也许这很愚蠢,但我对Elisp的了解不足,无法理解引用和求值方面发生的情况。

假设我有以下Elisp代码:

(add-to-list 'default-frame-alist '(width . 100))
(add-to-list 'default-frame-alist '(height . 50))

这将产生期望的 default-frame-alist 值:

((height 50)
 (width 100))

但是现在,如果我有这样的代码:

(setq my-frame-width 100)
(setq my-frame-height 50)
(add-to-list 'default-frame-alist '(width . my-frame-width))
(add-to-list 'default-frame-alist '(height . my-frame-height))

这将导致 -

((height my-frame-height)
 (width my-frame-width))

从框架几何角度来看,它从不评估那些变量。我如何使my-frame-width和height的实际值出现在这个alist中?我是否有太多引号?但我不能从add-to-list评估中删除任何引号...

2个回答

37

试试这样:

(setq my-frame-width 100)
(setq my-frame-height 50)
(add-to-list 'default-frame-alist `(width . ,my-frame-width))
(add-to-list 'default-frame-alist `(height . ,my-frame-height))

使用反引号(``)而不是引号('')允许您使用逗号(,)强制评估参数。

请参阅Elisp参考手册。键入C-x info,搜索elisp参考手册,然后在其中搜索反引号(backquote)。


正是我所寻找的,谢谢!像这样的问题提醒我应该系统地学习 elisp。 - Laurynas Biveinis
请参考Emacs lisp evaluate variable in alist以解决类似问题。 - Håkon Hægland
3
我喜欢反引号和逗号的直觉明显性。 - Cheeso

14

作为替代操作符mch回答中的反引号,您可以使用cons函数。该函数将使用第一个参数作为它的car,第二个参数作为它的cdr来构建一个cons单元。您代码中的点对符号是这个的简写形式。所以我们可以这样重写您的代码:

(setq my-frame-width 100)
(setq my-frame-height 50)
(add-to-list 'default-frame-alist (cons 'width my-frame-width))
(add-to-list 'default-frame-alist (cons 'height my-frame-height))

通过这种方式,您可以引用要按字面出现的符号(例如width和height),并评估需要其值的符号(例如my-frame-width和my-frame-height)。我更喜欢这种方法,因为它更加直观。当然,这确实是个人观点。以下是一些有关cons和list的更多信息,供日后参考。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接