我正在尝试通过阅读“不耐烦的斯卡拉”一书来学习斯卡拉。本书开始说要在REPL中输入代码,但这变得有些乏味,因此我开始将代码放入文件中,然后通过键入从命令行运行它scala myApp.scala
。一切似乎都正常。我决定通过将该行#!/usr/bin/env scala
放在顶部来使我的程序更容易运行,因此我可以./myFile.scala
从命令行键入内容。一切继续正常进行。
后来,这本书说“每个Scala程序必须从对象的main
方法开始...”,并给出了一个示例。紧接着,它说:“ main
您可以扩展App
特征并将程序代码放入构造函数主体中,而不是为应用程序提供方法,并给出一个示例。
我为什么要做任何这些事情?
我尝试将代码放入main
对象的方法中,但仍然可以使用,但是main
对我来说,对象和方法似乎毫无用处。
我尝试将代码放在扩展的对象中,App
当我尝试直接从命令行运行它时,它什么也没做。当我运行它scalac
然后运行时scala MyApp
,它运行良好,但是对于我正在从事的小型玩具项目而言,这些步骤似乎无用。
使对象具有main
方法或扩展对象的目的是App
什么?
编辑:有人将此问题标记为“ scala脚本和应用程序之间的区别”的重复。我可以说它不是重复的,因为它是关于具有main
方法并从扩展App
,而不是关于“脚本”和“应用程序”的含义。但是,它非常接近,因此我的问题可能是不必要的。我不知道该如何处理。随意关闭它或将其保持打开状态。
如果您所做的只是您正在从事的“小型玩具项目”,那可能没有任何目的。对于较大的项目,main()
方法创建与Java的兼容性,并且还向您的代码读者“全部从哪里开始”。当一个项目很大(成百上千个文件)并且您第一次接触它时,您可能想知道“我如何运行它?”,“执行从哪里开始?”。Java从C ++继承了这个约定,C从C继承了。C都是由函数组成的,您需要告诉编译器哪个函数需要编译为“开始执行”。手动执行代码时,您说“ scala myApp.scala”,它向Scala解释器解释了要执行哪个类。但是,如果您编写了一个更大的应用程序,编译了两个类并将它们放在一个JAR中,则需要一种方法来告诉JVM首先执行什么:指定对象的名称,main(args: Array[String])
你的小程序在没有 main 方法的情况下显示结果的原因是因为你实际上没有使用 scala 编译器。该程序只是使用 scala 解释器。所以像这样的程序:
A.scala:
println("just the interpreter")
Run Code Online (Sandbox Code Playgroud)
将运行并给出结果。但是,尝试使用 scalac 编译该程序将产生错误:
A.scala:1: error: expected class or object definition
通常,scala 项目不是 1 个文件中的指令列表。一旦开始使用类和对象构建应用程序,您就会发现您的程序不会产生任何结果。
B.scala:
object B {
println("won't show up")
}
Run Code Online (Sandbox Code Playgroud)
要获得结果,您需要添加一个 main 方法来告诉 scala 应用程序的入口点在哪里。
C.scala:
object C {
def main(args: Array[String]) =
println("shows up")
}
Run Code Online (Sandbox Code Playgroud)
为了方便起见,App 特征允许您通过简单地扩展 App 将任何对象转换为可执行程序。扩展这个特性会将整个对象主体变成 main 方法。
D.scala:
object D extends App {
println("shows up")
}
Run Code Online (Sandbox Code Playgroud)
现在您不能简单地打电话scala D.scala
来获取结果。你首先需要调用scalac D.scala
,然后你可以调用scala D
,你就会得到你期望的结果。
scala C.scala
之所以有效,是因为显式定义了 main 的对象是 scala 解释器处理的特殊情况。
归档时间: |
|
查看次数: |
1250 次 |
最近记录: |