scala 命令跳过在单例对象之外运行 main if 类



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 Appdef 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 方法

最新更新