【问题标题】:How does Scala handle Java style package statementsScala 如何处理 Java 风格的包语句
【发布时间】:2012-07-19 00:49:03
【问题描述】:

这听起来很尴尬。我的目的是了解 Scala 如何处理以 Java 风格编写的包语句。为此,我编写了一个小示例类(我将其命名为 DinnerTimeP.scala,如下所示:

package dinnertime
 class Dinner { 
  val veggie = "broccoli"
   def announceDinner(veggie: String) {
   println("Dinner happens to be tasteless " + veggie + " soup")
  }
 }

我有一个名为 scaladev 的文件夹,我在该文件夹下创建了包文件夹 Dinnertime。在这个包下生活着 DinnerTimeP.scala。然后在 DOS 命令上导航到晚餐时间并使用 scalac 编译文件 DinnerTimeP(这个名字听起来很傻),如下所示。

C:\scala-2.9.1.final\scala-2.9.1.final\scaladev\dinnertime>set CLASSPATH=.;C:\scala-  2.9.1.final\scala-2.9.1.final\scaladev

C:\scala-2.9.1.final\scala-2.9.1.final\scaladev\dinnertime>scalac DinnerTimeP.scala

我希望找到在 Dinnertime 文件夹下生成的 Dinner.class,它位于源文件 DinnerTimeP.scala 旁边。 为了确认我的理解,我在同一个文件夹下创建了一个 HelloWorld.java 程序:

package dinnertime;

public class HelloWorld {
  public static void main(String[] args) {
  System.out.println("Hello World");
}

}

我在命令行编译HelloWorld.java如下: C:\scala-2.9.1.final\scala-2.9.1.final\scaladev\dinnertime>javac HelloWorld.java

HelloWorld.class 文件是在其源文件旁边生成的。 这正是我想在 Scala 源文件及其编译文件中看到的确切情况。 相反,我在包文件夹 Dinnertime 中看到了一个由 Scala 生成的新包文件夹。

这可能很幼稚。我可能背叛了对 Scala 和包的基本理解,但我对这种行为感到困惑。 这是我无法向自己解释的问题:为什么要为新生成的类文件创建嵌套包。这是我希望通过自己的真诚努力解决的问题 因为我目前使用 Scala 的经验有限,所以我求助于 stackoverflow 上的 Scala 大师来帮助我了解发生了什么以及为什么? 这个嵌套包是由 Scala 而不是由 Java 创建的吗?

【问题讨论】:

    标签: java scala packages scalac


    【解决方案1】:

    首先尝试从根目录编译,使dinnertime成为子目录:

    $ javac dinnertime/HelloWorld.java
    

    和:

    $ scalac dinnertime/Dinner.scala
    

    它们都产生相同的输出,即在这两种情况下,.class 文件都放在dinnertime 子目录下。

    当您在包中运行编译器时,就会出现差异。原来javac 足够聪明,可以将目标二进制文件相对于根目录,而不是当前的目录。 scalac 不是这种情况,它总是使用当前目录作为基础。您可以使用-d 参数轻松解决此问题:

    $ cd dinnertime
    $ scalac -d .. Dinner.scala
    

    【讨论】:

    • 我刚刚运行了 scalac -d 这就是我所做的:C:\scala-2.9.1.final\scala-2.9.1.final\scaladev\dinnertime>scalac -d DinnerTimeP.scala scalac错误:DinnerTimeP.scala 不存在或不是目录 我正在做的事情似乎不正确。
    • @ilangogurusamy:-d 期待一些论点:scalac -d some/dir DinnerTimeP.scala
    • 更新:有效。我对 .. 很好奇,起初我忽略了它并运行 scalac -d,但是当我用 .. 尝试它时,它起作用了。太棒了。
    • 丹尼尔斯和你的回答对我来说都是完全可以接受的。因此,两者都是正确的。但我无法为两者设置正确的答案。
    • @ilangogurusamy:没问题,很高兴我们能提供帮助!
    【解决方案2】:

    Tomaszexplained 让它工作所需的一切,让我解释一下原因。

    Scala 不要求源文件位于反映包的目录层次结构中。也就是说,Dinner.scala 可以在任何地方:这根本不重要。

    而且,要非常清楚,即使你有一个复杂的包层次结构,很深并且每个级别都有多个子包,你可以将所有源文件放在一个目录中。 Scala 文件所在的目录不相关

    很抱歉这么强调它,但是来自 Java 可能很难掌握这一点。

    好的,现在,如何解释dinnertime/Dinner.class?好吧,JVM 要求将类文件放在与包名对应的目录层次结构中,因此即使 Scala 源文件可以放在任意目录中,scalac 也必须生成一个输出,其目录结构反映了包名。

    所以,要查看所有内容,Scala 并不关心您在哪个目录中,因此它忽略了您在名为 dinnertime 的目录中的事实。但是,由于源代码表明该类位于名为dinnertime 的包中,因此它创建了这样的目录并将类文件放入其中。它假设它的基础是当前目录,可以使用 -d 参数更改,根据 Tomasz 的回答。

    【讨论】:

    • 我现在都明白了。这是非常有用的信息。感谢您为解释内容而付出的出色反馈和辛勤工作。
    猜你喜欢
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多