可选参数默认值


26

Emacs Lisp不对可选参数的非null缺省值提供语法支持。提供这些参数的推荐惯用法是什么?

为了阐明我的观点,这是一种过于明确的方式。

(defun command (a &optional supplied-b)
  (let ((b (or supplied-b default-b)))
    (command-body a b)))

推荐的样式是什么(如果有的话)?

Answers:


24

除非使用@legoscia建议的Common Lisp扩展名,否则需要检查是否指定了可选参数。请注意,您实际上不需要在let这里使用。在我看来,这更惯用:

(defun command (a &optional b)
  (or b (setq b default))
  (command-body a b))

如评论中所建议,使用unless可能比or

(defun command (a &optional b)
  (unless b (setq b default))
  (command-body a b))

同样从注释中可以看出:更纯粹的功能风格将是使用let,就像在原始问题中一样,但是您不需要单独的变量名:

(defun my-command (a &optional b)
  (let ((b (or b default)))
    (command-body a b)))

当然,如果仅需要一次使用可选参数,则应该执行以下操作:

(defun my-command (a &optional b)
    (command-body a (or b default)))

7
-1:我不认为使用副作用表达式(例如setq“纯”布尔形式)的好风格or。我认为when这里肯定更合适,但通常let是建立或更改本地绑定的选择表达。IOW,原始代码对我来说更好。
lunaryorn 2015年

3
我同意类似的东西(unless b (setq b default)可能会更好。我个人认为这let是多余的,因为b它已经本地化了defun
glucas 2015年

3
这是一个品味问题,但是我更喜欢纯代码和纯绑定,例如,let而不是像这样的副作用形式setq。它是用于参数默认值的代码,但是大量使用setq来更改局部变量使代码难以阅读和遵循。我认为最好考虑所有本地绑定都是不可变的,并且只能使用建立新的绑定let。IOW比命令式更喜欢一种功能样式。
lunaryorn 2015年

22

您可以使用cl-defun,它可以为可选参数指定默认值:

(cl-defun command (a &optional (b default-b))
  (command-body a b))

在这种情况下default-b,每次调用该函数时都会评估默认值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.