什么是脚本引擎?

10

我在这里看到,区分编程语言和脚本语言之间的关键在于脚本引擎。但是我不明白它是如何工作的,所以我不知道它们之间有何区别。

例如,我看到Java代码调用导入库中的方法,但它似乎与Python或Ruby代码并没有“足够的不同” - 它们都是脚本语言,对吗?我想这也与过程式和面向对象的范式有关,但最终,我仍然看不出它们被分类为什么样的。

编辑: 关于脚本引擎是一个解释器... 那Java不是一种解释型语言吗?我知道有编译好的字节码,但是这对我来说还是不合理。


5
是的,Java(和C#)的典型实现在虚拟机中运行字节码,也就是说解释器,就像Python或Ruby的典型实现一样(实际上它可以是相同的解释器;-)。因此,正如您所注意到的那样,这种区别是相当站不住脚的。 - Alex Martelli
1
Java不是一种解释性语言。你有一个名为javac的编译器和(虚拟)机器对象二进制文件称为class文件。 - alphazero
1
Java不被认为是一种解释性语言。你编写Java代码,然后有一个明确的编译步骤,将Java代码转换为字节码。然后在Java虚拟机中解释这些字节码。通常,当人们说“解释性语言”时,他们指的是一种可以直接运行代码而无需明确编译步骤的语言。(“解释器”可能使用即时编译作为速度优化。)这很模糊:即使是所有人都同意是“编译”的语言,如C,也可以有解释器。(谷歌搜索“C解释器”!) - steveha
4
Python做的事情与其他编程语言类似,只是你没有注意到。你可以让它仅编译一个文件,然后就会得到一个.pyc字节码文件,这本质上就是编译后的Python代码。 - Javier
6个回答

12

在“脚本语言”和“编程语言”之间没有硬性的界限。

“脚本语言”的特点通常包括:

  • 垃圾回收内存管理器,无需显式分配和释放对象

  • 能够简单地执行命令,不需要大量样板代码。 Java通常被用作反例。 在Python中,您只需输入print("Hello, world!") 即可完成,但在Java中,您需要更多的语法(此示例 有七行代码)。

  • 与上述相关的是,在“脚本语言”中通常不需要显式声明变量,而且很少需要声明变量类型。一些脚本语言(例如JavaScript)会狂暴地强制转换类型,而其他一些(例如Python)则是强类型的,并在类型不匹配时引发异常。

  • 无需显式编译或链接步骤; 您只需编写代码并运行它即可。(“脚本语言”仍然可以在内部进行即时编译;例如Python就是这样做的。)

除了这些基础知识外,“脚本语言”可以从类似于MS-DOS中的“批处理”语言这样原始和琐碎的东西,一直到像Python、Ruby等表达力强大的语言。


1
大部分都同意,除了第一点:这不是完全正确的;我所知道的唯一不进行垃圾回收的语言是C/C++。 - hasen
3
@hasanj,你的“它并不完全正确”是什么意思?我声称任何需要你自己使用malloc()free()分配和释放内存的语言都不符合“脚本语言”的标准。我没有声称“非脚本语言”必须强制你管理内存。 - steveha
“coerce types with wild abandon” 加1分——在阅读SO时很少有机会大笑... - Ed Graham
1
@steveha -- 确实。你的观点非常清晰,写作风格既富有表现力又富有信息量。继续保持好工作! - Ed Graham
1
@steveha 太多人混淆了“动态类型”(变量不关心其值的类型)和“弱类型”(将被强制转换为适当的类型或等效物,只有在这种情况下才会失败);同样,“严格类型”(变量确实关心其值的类型,并且每个值只能有一个类型)和“强类型”(根本不进行强制转换;如果它们不符合要求,就是一个错误)。 - anon
显示剩余2条评论

6
你基本上发现了脚本语言和“非脚本”语言之间的区别是相当人为的。Python可以编译成JVM bytecode(使用Jython),我相信Ruby也可以——然后运行Python或Ruby代码的"引擎"将是一个JVM,与运行Java代码(或Scala代码等)的相同的"引擎"。.NET和IronPython(或IronRuby)也是如此——这时,"引擎"是微软的CLR,就像C#、Boo等一样。通常被称为"脚本"的语言都是动态类型的语言...但我从未听说过其他重要的动态类型语言,比如Smalltalk、Mozart/OZ或Erlang会用到这个术语...;-)。

3

我知道你已经接受了一个答案,但是还存在一些不确定性。

当提到一个“脚本引擎”时,通常指的是一个嵌入在模板中的小型语言,用于生成文本输出或文档。例如,Freemarker和Velocity经常被称为脚本引擎。Erb也可以放在这里,但奇怪的是它并没有经常被称为脚本引擎。

一个“脚本语言”通常不需要编译步骤,因此可以更简单地作为shell脚本运行或从shell脚本中运行。这包括awk、perl、tcl、python、ruby等等。这些语言通常需要简洁,并且类型安全通常是可选的。Windows支持许多语言在其“脚本主机”设施中。这使得脚本语言可以暴露给Windows中的各种组件。

因此,像Java这样的完全编译的语言可能会以字节码形式运行,并且可以被认为是解释的,但关键是有一个明确的编译步骤,没有解释器(至少在Sun JRE中)为Java代码提供运行时可执行环境。

其他语言如VBA是嵌入式的,上述许多语言也可以被嵌入。嵌入式语言可以被称为主机应用程序的脚本引擎。

在我看来,脚本引擎解释程序指令,并反过来指示更大的主机应用程序或系统。这些指令立即执行,不考虑任何剩余的指令。

许多Lisp没有数据和代码之间的区别,可能在运行时动态编译。解释、编译和执行步骤可供Lisp程序员像其他语言中操作数据一样操作。


2
你所说的可能是最接近的东西是解释器

在计算机科学中,解释器通常指执行编程语言指令的计算机程序。尽管解释和编译是实现编程语言的两种主要方式,但它们并不完全不同,其中一个原因是大多数解释系统也执行一些翻译工作,就像编译器一样。

基本上,解释器(或脚本引擎,如果您愿意)是将脚本在执行时转换为机器代码的组件(与在执行时间之前创建机器代码的编译器相对)。

0
“脚本语言”可能被称为口头语。该术语没有很好地定义,人们对哪些语言是脚本语言有不同的看法。这有时有助于传达语言属性的模糊概念(参见steveha's answer)。
“脚本语言”也可能指特定语言的使用。例如,某个软件可能使用Lua作为其脚本语言——最终用户用来自动化(或“脚本化”)复杂任务的语言。

0
一种有用的区分脚本/解释型语言和编译型语言的方法是,你通常可以将脚本语言的解释器嵌入到编译项目中,比如游戏引擎。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接