3

这听起来很尴尬。我的目的是了解 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 创建?

4

2 回答 2

5

首先尝试从根目录编译,所以这dinnertime是一个子目录:

$ javac dinnertime/HelloWorld.java

和:

$ scalac dinnertime/Dinner.scala

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

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

$ cd dinnertime
$ scalac -d .. Dinner.scala
于 2012-07-19T19:08:57.180 回答
5

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

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

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

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

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

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

于 2012-07-19T19:28:07.137 回答