【问题标题】:Scala println not working with App traitScala println 不适用于 App 特征
【发布时间】:2012-06-24 07:24:51
【问题描述】:

当我使用 scala App 特征时,我无法让 println 工作。

这个简单的例子按预期打印,

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

但是一旦我引入了它没有的特征,

object HelloWorld extends App {
  println("Hello, world!")
}

我没有收到任何错误,但没有任何内容打印到控制台。

【问题讨论】:

    标签: scala scripting println


    【解决方案1】:

    您是否先编译它(运行 scalac HelloWorld.scala)?看到这条评论:http://www.scala-lang.org/node/9483#comment-40627

    编辑添加更多解释: 第一个版本实际上是编译的。没有显式 main 方法的 Scala 文件未编译为脚本运行。这意味着对于您的第二个版本,文件中的命令按顺序运行,就好像它们已被输入到解释器中一样——因此,对象 HelloWorld 被创建,但没有对其调用任何方法。这里有更多关于 Scala 作为脚本语言的信息(滚动到第 5 步):http://www.artima.com/scalazine/articles/steps.html

    【讨论】:

    • 奇怪。这似乎是解释器的一个奇怪的限制。有什么解释为什么我需要编译这个类才能让它工作吗?特质在解释器中不起作用吗?
    • 并且特征在解释器中确实有效,但 App 是一种特殊情况。它通常表现为“App 将代码包装在其实现对象中的 main 方法中”,但实际上并非如此——而是将代码粘贴到称为 delayInit 的东西中,它在 main 方法被调用时被调用,而不是在创建对象,这通常是在调用对象声明中的裸代码时。
    • 没问题——如果你对它充满好奇的话,在 Josh Suereth 的新书 Scala in Depth 的第 4 章中,对 Scala 初始化的一些潜在陷阱进行了更深入的描述:)
    • @James,@Kelsey,它在两种情况下都已编译 - 怎么可能不... JVM 运行在字节码上,而不是文本上。如果您不声明外部对象并将其作为脚本运行,您的命令将被包装在一个临时对象中并编译/运行 - 但与运行scalac 不同,.class 文件不会保存到磁盘。有人在某个时候决定,如果您的脚本由一个带有main 方法的对象组成,而不是包装它,它只会编译该对象并运行它。对App 不这样做似乎是一种疏忽,但无论如何,这不是你应该依赖的行为,IMO。
    • @LuigiPlinge,好点子。该脚本的“解释”方式与代码在 Scala“解释器”中运行的方式相同——它被编译为临时对象,并且不保存 .class 文件。
    【解决方案2】:

    添加一行

    object HelloWorld extends App {
      /* code */
    }
    
    HelloWorld.main(args)
    

    在文件的末尾。

    类定义了方法,但它也需要被调用。

    【讨论】:

      【解决方案3】:

      根据 http://www.scala-lang.org/api/current/scala/App.html

      你想做的事

      object Main extends App {
       Console.println("Hello World: " + (args mkString ", "))
      }
      

      【讨论】:

        猜你喜欢
        • 2017-06-20
        • 1970-01-01
        • 2023-03-29
        • 2011-11-16
        • 2014-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-13
        相关资源
        最近更新 更多