scala命令跳过在singleton对象之外运行main if class

编辑:
Main method is not called in Scala script是相关的(特别是RégisJean-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

产生预期的输出:

Scala Version: 2.11.7
Tyrannotitan, Weight: 4900 kg
Animantarx, Weight: 300 kg

但是,如果将Dinosaur类放在单例对象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"
}

在第二个版本中,要获得控制台输出,必须首先编译代码,然后单独运行MiniScalaApp.class

$scalac /myProject/src/main/scala/MiniScalaApp.scala
$scala MiniScalaApp

问题:scala命令以不同方式处理代码的原因是什么?

最佳答案 scala -help解释了所有.

A file argument will be run as a scala script unless it contains only
self-contained compilation units (classes and objects) and exactly one
runnable main method. In that case the file will be compiled and the
main method invoked. This provides a bridge between scripts and
standard scala source.

所以后一种情况是定义对象和类,它将代码作为脚本运行.
用另一种方式来说,它的作用与…完全相同

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

只有define.so你需要明确地调用它.

MiniScalaApp.main(Array())

除此之外,如果文件只有一个top-lebel object.def mainis,则无法使用对象Foo扩展App.

点赞