如何根据 elisp 中的一个条件设置一堆变量?
how to set a bunch of variables depending on one condition in elisp?
假设我想根据一个条件设置 bar
和 baz
的值,这在两种情况下都是相同的,比如说 foo
的值。使用 let
特殊形式,我做这样的事情
(let ((bar (if foo 1 2))
(baz (if foo 3 4)))
... )
虽然上面的程序是正确的,但看起来有点奇怪,因为它检查了两次foo
的值。在这种情况下是否可以使用惯用语来避免双重检查?
您可以使用 cl-lib.el
提供的多个值,Emacs 的 Common Lisp 扩展:
(multiple-value-bind (bar baz)
(if foo (values 1 3) (values 2 4))
...)
您可能希望在不同的函数中提取这两种情况。
我在 elisp 中唯一能想到的答案(没有多个值)是这样的相当可怕的东西:
(apply (lambda (bar baz)
...)
(if foo
(list 1 2)
(list 3 4)))
这通常很方便,尽管在可以提供文字列表的良好情况下显然不需要这样做。
你可以把它包装在一个宏中:下面就是这样,尽管它迫切需要一些错误检查(elisp 太烦人了,我不想花更多的时间在它上面——至少它有现在反引号)。
(defmacro plet (vars-vals &rest forms)
`(apply (lambda ,(car vars-vals)
,@forms)
,(cadr vars-vals)))
然后你的表达式将变成(这次使用文字列表)
(plet ((bar baz) (if foo '(1 2) '(3 4)))
...)
您不需要在 let 表单本身中设置值。 let 形式创建本地绑定,之后您可以根据需要设置值。
(let (bar baz)
(if foo
(setq bar 1
baz 2)
(setq bar 3
baz 4))
...)
假设我想根据一个条件设置 bar
和 baz
的值,这在两种情况下都是相同的,比如说 foo
的值。使用 let
特殊形式,我做这样的事情
(let ((bar (if foo 1 2))
(baz (if foo 3 4)))
... )
虽然上面的程序是正确的,但看起来有点奇怪,因为它检查了两次foo
的值。在这种情况下是否可以使用惯用语来避免双重检查?
您可以使用 cl-lib.el
提供的多个值,Emacs 的 Common Lisp 扩展:
(multiple-value-bind (bar baz)
(if foo (values 1 3) (values 2 4))
...)
您可能希望在不同的函数中提取这两种情况。
我在 elisp 中唯一能想到的答案(没有多个值)是这样的相当可怕的东西:
(apply (lambda (bar baz)
...)
(if foo
(list 1 2)
(list 3 4)))
这通常很方便,尽管在可以提供文字列表的良好情况下显然不需要这样做。
你可以把它包装在一个宏中:下面就是这样,尽管它迫切需要一些错误检查(elisp 太烦人了,我不想花更多的时间在它上面——至少它有现在反引号)。
(defmacro plet (vars-vals &rest forms)
`(apply (lambda ,(car vars-vals)
,@forms)
,(cadr vars-vals)))
然后你的表达式将变成(这次使用文字列表)
(plet ((bar baz) (if foo '(1 2) '(3 4)))
...)
您不需要在 let 表单本身中设置值。 let 形式创建本地绑定,之后您可以根据需要设置值。
(let (bar baz)
(if foo
(setq bar 1
baz 2)
(setq bar 3
baz 4))
...)