为什么Scala程序有主要方法或扩展应用程序特征?

时间:2016-11-11 20:44:52

标签: scala

我正在尝试通过阅读书籍" Scala for the Impatient"来学习Scala。本书开始说要将代码输入REPL,但这变得有点乏味,所以我开始将我的代码放在一个文件中,然后通过键入scala myApp.scala从命令行运行它。一切似乎都很好。我决定通过将行#!/usr/bin/env scala放在顶部使我的程序更容易运行,所以我可以从命令行输入./myFile.scala。一切都继续正常。

后来,这本书说"每个Scala程序必须以对象的main方法开始......"并给出一个例子。紧接着,它说"您可以扩展main特征并将程序代码放入构造函数体中,而不是为您的应用程序提供App方法。并举例说明。

为什么我要做这些事情?

我尝试将我的代码放在一个对象的main方法中,它仍然有用,但是对象和main方法对我来说似乎毫无用处。

我尝试将我的代码放在一个扩展App的对象中,当我尝试直接从命令行运行它时,它没有做任何事情。当我通过scalac运行scala MyApp然后运行main时,它运行正常,但对于我正在进行的小型玩具项目来说,这似乎是无用的步骤。

使用App方法创建对象或扩展main的对象的目的是什么?

编辑:有人将此问题标记为" scala脚本与应用程序"之间的区别。我会说它可以说是不重复的,因为它是因为它是关于App方法并且从telnet 12.34.56.789 27017 延伸而不是关于词的含义" script"和"申请"。但是,它非常接近,所以我的问题可能是不必要的。我不知道应该如何对待这个问题。您可以随意关闭它,或者在您认为合适时将其打开。

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

小程序在没有main方法的情况下显示结果的原因是因为您实际上并未使用scala编译器。该程序只是使用scala解释器。 所以一个程序如:

A.scala:

println("just the interpreter")

将运行并给出结果。但是,尝试使用scalac编译此程序将产生错误: A.scala:1: error: expected class or object definition

通常,scala项目不是1个文件中的指令列表。一旦开始使用类和对象构建应用程序,您将看到程序不会产生任何结果。

B.scala:

object B {
    println("won't show up")
}

要获得结果,您需要添加一个main方法来告诉scala应用程序的入口点在哪里。

C.scala:

object C {
    def main(args: Array[String]) =
        println("shows up")
}

为方便起见,App trait允许您通过简单地扩展App将任何对象转换为可执行程序。扩展此特征会将整个对象体转换为主方法。

D.scala:

object D extends App {
    println("shows up")
}

现在你不能简单地调用scala D.scala来获得结果。您首先需要拨打scalac D.scala,然后拨打scala D,即可获得预期的结果。

scala C.scala仅起作用,因为显式定义的主对象是由scala解释器处理的特殊情况。

答案 2 :(得分:0)

您可以使用这两种方法运行程序。但是Scripts用于小程序,而声明 var polygon = geoXml.docs[0].gpolygons[0]; if (polygon) { polygon.infoWindow = new google.maps.InfoWindow({content: html}); google.maps.event.addListener(polygon, 'mouseover', function(e) { var latLng = e.latLng; this.setOptions({fillOpacity:0.80}); polygon.infoWindow.setPosition(latLng); polygon.infoWindow.open(map); }); google.maps.event.addListener(polygon, 'mouseout', function() { this.setOptions({fillOpacity:0.35}); polygon.infoWindow.close(); }); } else console.log("event:"+event+", expires:"+expires); 方法用于大型程序。传统上运行字节代码的JVM识别main方法,并从main方法的第一行开始执行程序。