0

我试图查看数据与代码替换是如何工作的,当eval在一个函数中使用类似的东西时,它可以让我传入任何打印命令,如print princetc 和一些文本,并在其输出中使用该命令:

(defun print-test (fn text)
  (eval '(fn 'text)))

我尝试了各种方法,但我无法让它运行。我也试过:

(defun print-test (fn text)
  (eval ('fn 'text)))

..和其他变体。所以我显然错过了一些东西。我希望能够做到这一点:

(print-test 'princ 'some-text)

我通常会得到一个错误fn is undefined。但是由于我正在实时评估代码,我认为它可以fn从我的输入中得到?

我意识到还有其他方法可以做到这一点,比如传入一个实际的函数对象,#'princ但我很好奇该eval机制是如何动态生成代码的。

4

1 回答 1

3

像这样的错误fn is undefined并没有告诉您princ未定义,而是该符号fn没有函数绑定。你不想调用符号fn,你想调用变量的值fn

看起来您想要评估一个列表,其第一个元素是 的值,fn第二个元素是 的值text。您可以使用listin 中的函数创建这样一个列表(list fn text)。然后你能用它打电话吗eval

(defun print-test (fn text)
  (eval (list fn text)))

您也可以使用反引号表示法,并执行

(defun print-test (fn text)
  (eval `(,fn ,text)))

在这些情况下,如果您想获得与 相同的效果(princ 'hi),则需要fn成为符号princtext成为列表 'hi(是的,列表,因为'hi是 的简写(quote hi))。你会这样打电话,然后:

(print-test 'princ ''hi)

如果第二个参数应该始终在生成的文本中被引用,您也可以使用以下任何一种:

(eval `(,fn ',text))
(eval `(,fn (quote ,text)))
(eval (list fn (list 'quote text)))

尽管如此,这似乎是一种非常奇怪的使用方式eval。除非有特别好的理由,否则为什么不直接使用funcall?毕竟,如果fn作为一种评估形式的汽车是合法的,并且text是一个论点,那么这不能简单地成为以下内容吗?

(defun print-test (fn text)
  (funcall fn text))

当然,这会有点不同。在这里,如果您想要与 相同的效果(princ 'hi),您只需传递符号princhi

(print-test 'princ 'hi)
于 2013-11-15T06:32:06.813 回答