5

I am brand new to Scala, and I was wondering why the main method is not running in this script?

class Word {
}

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello, world!")
  }
}

The interesting thing is that it works fine when i remove the Word class. Why is this? And how do I fix it?

4

4 回答 4

9

这种奇怪行为的原因很简单。当使用scala在命令行中传递的脚本名称运行可执行文件时(如 中scala hello.scala),默认情况下会尝试“猜测”要运行的内容。如果文件只包含一个具有合适main方法的对象(这意味着它也是一个合适的程序入口点),main则运行该方法。否则,scala 文件将被解释为适当的脚本(在顶层接受语句并逐行运行,就像在交互模式下一样)。因此,确实有两种使用 scala 解释器可执行文件运行 scala 文件的方法(第一种很少使用)。

因此,一旦您在源文件中添加了另一个类,第一种执行模式(调用 main 方法)就不再触发,并且您退回到标准的逐行解释。因此,除非您明确调用它,否则不再调用您的 main 方法。

作为参考,这里是scala -help(强调我的)的输出:

用法:scala <options> [<script|class|object|jar> <arguments>] 或 scala -help

还允许使用 scalac 的所有选项(请参阅 scalac -help)。除了 scala 的选项之外,第一个给定的参数指定要运行的内容。可运行的目标是:

  • 包含 scala 源的文件
  • 已编译类的名称
  • 具有有效 Main-Class 属性的可运行 jar 文件
  • 或者如果没有给出参数,则启动 repl(交互式 shell)

到达 java 运行时的 scala 选项:

-Dname=prop 直接传递给 java 以设置系统属性
-J -J 被剥离并按原样传递给 java
-nobootcp 不要将 scala jar 放在引导类路径上(较慢)

其他启动选项:

-howtorun 运行什么 (默认值:猜测)
-i 在启动 repl 之前预加载
-e 像在 repl 中输入一样执行
-save 将编译后的脚本保存在 jar 中以备将来使用
-nc 没有编译守护进程:不要离线使用 fsc编译器

文件参数将作为 scala 脚本运行,除非它只包含自包含的编译单元(类和对象)和一个可运行的 main 方法。在这种情况下,将编译文件并调用 main 方法。这在脚本和标准 scala 源之间提供了一座桥梁。

插件“延续”的选项:
-P:continuations:enable 启用延续

于 2013-06-07T21:15:35.493 回答
9

如开始使用 scala中所示,当将 scala 文件作为脚本运行时,您应该显式调用 main 方法:

class Word {
}

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello, world!")
  }
}

HelloWorld.main(args)

如果你想编译和运行,你必须给出持有该main方法的对象的名称:

scalac test.scala
scala HelloWorld
于 2013-06-07T18:56:12.010 回答
5

其实你写的不是 Scala 脚本,而是一个简单的 Scala 程序。Scala 脚本不同于简单程序的组织和运行方式,没有编译阶段,Scala 编译器将逐行解释源文件,就像在 REPL 会话中一样。

要从您的文件中制作 Scala 脚本,只需离开:

println("This is a scala script") 

并将其保存在*.scala文件中,然后scala在终端窗口中使用命令运行它,而无需任何先前的scalac调用。Scala 编译器会自动确定这是一个脚本,因为源文件以表达式结尾。当您放在HelloWorld.main(args)文件末尾时,它将作为脚本文件执行,但是带有main()方法的类和伴随对象已完全过时

于 2013-06-07T19:32:50.593 回答
0

如果您使用某种 Unix,您可以通过在文件顶部添加pound bang指令来将 Scala 脚本作为 shell 脚本运行。

例如,在名为 的文件中键入以下内容helloarg

#!/bin/sh
exec scala "$0" "$@"
!#
// Say hello to the first argument
println("Hello, "+ args(0) +"!")

首字母#!/bin/sh必须是文件中的第一行。
一旦你设置了它的执行权限:

$ chmod +x helloarg

您可以将 Scala 脚本作为 shell 脚本运行,只需说:

$ ./helloarg globe

如果您使用的是 Windows,则可以通过命名文件helloarg.bat并将其放在脚本顶部来实现相同的效果:

::#!
@echo off
call scala % 0 % *
goto :eof
::!#
于 2014-04-15T10:58:16.257 回答