【发布时间】:2015-01-31 16:52:54
【问题描述】:
以下代码
(setq func 'concat)
(apply func "a" "b")
抛出以下错误
***Eval error*** Wrong type argument: listp, "b"
为什么apply 将第三个位置的所有参数都作为 'func' 的参数?
【问题讨论】:
以下代码
(setq func 'concat)
(apply func "a" "b")
抛出以下错误
***Eval error*** Wrong type argument: listp, "b"
为什么apply 将第三个位置的所有参数都作为 'func' 的参数?
【问题讨论】:
apply 将列表作为其最后一个参数,因此这些调用是正确的:
(apply func "a" '("b"))
(apply func '("a" "b"))
要传递普通参数,您可以改用funcall:
(funcall func "a" "b")
最终,你也可以使用apply,如下所示
(apply func "a" "b" nil)
或
(apply func "a" "b" ())
这是因为 nil 和 () 在 Emacs Lisp 中被视为空列表。
【讨论】:
apply 的典型用法是将一个函数应用于参数列表,然后将该列表“传播”到参数上。另一方面,funcall 是唯一需要的,因为 elisp 将函数和变量绑定分开。
(defun wrapped-fun (fun a b)
"Wrapped-fun takes a function and two arguments. It first does something,
then calls fun with the two arguments, then finishes off doing
something else."
(do-something)
(funcall fun a b) ;; Had function and variable namespaces been the same
;; this could've been just (fun a b)
(do-something-else))
【讨论】:
apply 接受一个函数和一个列表,所以使用
(apply func '("a" "b"))
或者只是
(func "a" "b")
【讨论】: