有语言和没有语言的能力没有区别eval
。你总是可以eval
用一种没有它的语言来实现自己,尽管它在某些语言(Lisp)中更容易,而在其他语言(C)中更难。这就是为什么我们知道它不会为语言添加任何新功能。
Eval 通常被认为是“强大但危险且在生产代码中不必要的”。如果您曾经审查过您的源代码,并且它使用了eval
.,那么您将不得不习惯人们告诉您不要使用eval
. 通常,如果您使用eval
,有一种更直接、更安全的方式来完成相同的任务。
安全漏洞
该eval
功能通常会导致安全漏洞,例如在 Web 应用程序中。例如,在 Python 中:
i = input('Enter a number> ')
Python 3.x 之前的input
函数评估用户输入,导致安全问题:
输入一个数字> __import__('os').system('rm -rf $HOME') # 不要尝试这个
这可以在完全沙盒化的运行时中避免,例如 JavaScript、Lua、CLI 等。但是,在没有沙盒化的代码中,安全使用太难了eval
。
REPL
一个光荣的用途eval
是 REPL,它是软件开发的有用工具。在 Google Chrome 中,您现在可以通过按下来Ctrl+Shift+I启动 REPL——只需在出现的框中输入 JavaScript 即可。Firefox 和 Safari 也都有 REPL。
为什么不包括eval
?
该eval
功能通常非常复杂。将其包含在标准库中意味着库或运行时必须包含该语言的完整编译器或解释器,这是一大块代码。这就是为什么您通常会eval
在通常解释或 JITed 的语言中看到的原因——Lisp、Python 和 JavaScript 运行时通常已经包含一个完整的编译器,所以eval
没有额外的包袱。
for C 的实现eval
是真正的野兽,因此它们是可选的并被塞入库中。