EDIT:在Scala脚本中调用的主要方法是相关的(特别是来自Régis Jean-Gilles的答案)。这篇文章提供了描述问题的更多详细信息。答案(通过 suish)给出了一个更实际的演示来解释 scala 命令的行为。
MiniScalaApp.scala的内容
object MiniScalaApp {
def main(args: Array[String]) = {
println(s"Scala Version: ${scala.util.Properties.scalaPropOrElse("version.number", "unknown")}")
println(new Dinosaur("Tyrannotitan", 4900))
println(new Dinosaur("Animantarx ", 300))
}
class Dinosaur (name:String, weightKG: Int) {
override def toString = f"$name, Weight: $weightKG kg"
}
}
在命令行执行方式为:
$ scala /myProject/src/main/scala/MiniScalaApp.scala
生成预期的输出:
斯卡拉版本:2.11.7
暴龙泰坦, 重量: 4900 kg
阿尼曼塔克斯, 重量: 300 公斤
但是,如果将恐龙类放置在单例对象 MiniScalaApp 之外,则 scala 命令不会生成控制台输出,也不会产生错误消息。
object MiniScalaApp {
def main(args: Array[String]) = {
println(s"Scala Version: ${scala.util.Properties.scalaPropOrElse("version.number", "unknown")}")
println(new Dinosaur("Tyrannotitan", 4900))
println(new Dinosaur("Animantarx ", 300))
}
}
class Dinosaur (name:String, weightKG: Int) {
override def toString = f"$name, Weight: $weightKG kg"
}
在此第 2 版本中,要获取控制台输出,必须先编译代码,然后分别运行 MiniScalaApp.class
$ scalac /myProject/src/main/scala/MiniScalaApp.scala
$ scala MiniScalaApp
问:scala 命令以不同的方式处理代码的原因是什么?
scala -help
解释了一切。
文件参数将作为 scala 脚本运行,除非它只包含 自包含编译单元(类和对象)和一个 可运行的主方法。 在这种情况下,文件将被编译,并且 调用的主方法。 这在脚本和 标准斯卡拉源。
所以后一种情况是定义对象和类,它将以脚本的形式运行代码。换句话说,它所做的与
...scala> :paste
// Entering paste mode (ctrl-D to finish)
object MiniScalaApp {
def main(args: Array[String]) = {
println(s"Scala Version: ${scala.util.Properties.scalaPropOrElse("version.number", "unknown")}")
println(new Dinosaur("Tyrannotitan", 4900))
println(new Dinosaur("Animantarx ", 300))
}
}
class Dinosaur (name:String, weightKG: Int) {
override def toString = f"$name, Weight: $weightKG kg"
}
// Exiting paste mode, now interpreting.
defined object MiniScalaApp
defined class Dinosaur
仅 defining.so 需要显式调用它。
MiniScalaApp.main(Array())
除此之外,如果文件只有一个 top-lebel 对象,则无法使用object Foo extends App
。def main
是必需的。
如果有多个顶级类/对象,似乎您需要显式调用 main
方法:
object MiniScalaApp {
def main(args: Array[String]) = {
println(s"Scala Version: ${scala.util.Properties.scalaPropOrElse("version.number", "unknown")}")
println(new Dinosaur("Tyrannotitan", 4900))
println(new Dinosaur("Animantarx ", 300))
}
}
class Dinosaur (name:String, weightKG: Int) {
override def toString = f"$name, Weight: $weightKG kg"
}
MiniScalaApp.main(args);
请参阅此处:在 Scala 脚本中未调用 Main 方法