为什么伊娃是邪恶的?

为什么伊娃是邪恶的?

我知道Lisp和Scheme程序员通常说eval除非绝对必要,否则应避免。对于几种编程语言,我已经看到了相同的建议,但我还没有看到反对使用eval..我在哪里可以找到关于使用的潜在问题的说明?eval?

例如,我知道GOTO在过程编程中(使程序不可读和难以维护,使安全问题很难找到,等等),但我从未见过反对的论点。eval.

有趣的是,同样反对GOTO应该对延续有效,但我看到,例如,阴谋家不会说续写是“邪恶的”-你在使用它们时应该小心。他们更有可能对使用eval而不是使用连续的代码(据我所见-我可能错了)。


SMILET
浏览 529回答 3
3回答

MYYA

一个人不应该使用的原因有几个。EVAL.初学者的主要原因是:你不需要它。示例(假设CommonLisp):用不同的运算符计算表达式:(let ((ops '(+ *)))   (dolist (op ops)     (print (eval (list op 1 2 3)))))最好写成:(let ((ops '(+ *)))   (dolist (op ops)     (print (funcall op 1 2 3))))有许多初学者学习Lisp认为他们需要的例子。EVAL,但是他们不需要它-因为表达式是计算的,而且还可以计算函数部分。大多数情况下,使用EVAL表明对评估人员缺乏了解。宏也是同样的问题。通常,初学者编写宏,他们应该在哪里编写函数-不了解宏的真正用途,也不理解函数已经完成了任务。它常常是作业使用的错误工具。EVAL它经常表明初学者不理解通常的Lisp评估规则。如果你觉得你需要EVAL,然后检查一下是否有类似的事情FUNCALL, REDUCE或APPLY可以用来代替。FUNCALL-调用带有参数的函数:(funcall '+ 1 2 3)REDUCE-调用值列表上的函数,并将结果合并:(reduce '+ '(1 2 3))APPLY-调用以列表作为参数的函数:(apply '+ '(1 2 3)).问:我真的需要val吗?还是编译器/计算器已经满足了我的实际需要?避免的主要原因EVAL对于稍微高级的用户:您希望确保编译了您的代码,因为编译器可以检查代码中的许多问题,并生成更快的代码,有时(即因子1000;-)更快。构建并需要评估的代码不能尽早编译。任意用户输入的Eval存在安全问题。评估的一些用途EVAL可能在错误的时间发生并造成构建问题。为了用一个简化的例子来解释最后一点:(defmacro foo (a b)   (list (if (eql a 3) 'sin 'cos) b))因此,我可能想要编写一个基于第一个参数的宏SIN或COS.(foo 3 4)是吗?(sin 4)和(foo 1 4)是吗?(cos 4).现在我们可能有:(foo (+ 2 1) 4)这并不能给出预期的结果。然后,可能需要修复宏。FOO通过评估变量:(defmacro foo (a b)   (list (if (eql (eval a) 3) 'sin 'cos) b))(foo (+ 2 1) 4)但这样做还是行不通的:(defun bar (a b)   (foo a b))在编译时不知道变量的值。避免的一般重要原因EVAL:它经常被用于丑陋的黑客。

杨__羊羊

eval(在任何语言中)都不像电锯一样邪恶。它是一种工具。它恰好是一种强大的工具,当被误用时,它可以切断四肢和内脏(比方说),但程序员工具箱中的许多工具也是如此,包括:goto和朋友基于锁的线程延续宏(高元或其他)指针可重新启动的例外自修改码.还有成千上万的演员如果你发现自己不得不使用任何这些强大的,潜在的危险工具,问自己三次“为什么?”在一条链子里。例如:“我为什么要用eval“因为福”为什么有必要“因为.”如果你走到了这条链的尽头,而工具看起来仍然是正确的,那就去做吧。把地狱记录下来。把地狱弄出来。反复检查正确性和安全性。但是做吧。

尚方宝剑之说

伊瓦尔很好,只要你知道一点儿没错里面是什么。进入它的任何用户输入都必须进行检查和验证。如果你不知道如何百分之百确定,那就不要去做。基本上,用户可以为所讨论的语言输入任何代码,然后执行。你可以想象他能造成多大的伤害。
打开App,查看更多内容
随时随地看视频慕课网APP