为什么Scala程序应具有主要方法或扩展App特性?

Eli*_*ria 1 scala

我正在尝试通过阅读“不耐烦的斯卡拉”一书来学习斯卡拉。本书开始说要在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,而不是关于“脚本”和“应用程序”的含义。但是,它非常接近,因此我的问题可能是不必要的。我不知道该如何处理。随意关闭它或将其保持打开状态。

rad*_*scu 5

如果您所做的只是您正在从事的“小型玩具项目”,那可能没有任何目的。对于较大的项目,main()方法创建与Java的兼容性,并且还向您的代码读者“全部从哪里开始”。当一个项目很大(成百上千个文件)并且您第一次接触它时,您可能想知道“我如何运行它?”,“执行从哪里开始?”。Java从C ++继承了这个约定,C从C继承了。C都是由函数组成的,您需要告诉编译器哪个函数需要编译为“开始执行”。手动执行代码时,您说“ scala myApp.scala”,它向Scala解释器解释了要执行哪个类。但是,如果您编写了一个更大的应用程序,编译了两个类并将它们放在一个JAR中,则需要一种方法来告诉JVM首先执行什么:指定对象的名称,main(args: Array[String])


soo*_*ote 5

你的小程序在没有 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 解释器处理的特殊情况。