Scala如何处理Java样式包语句

时间:2012-07-19 19:01:19

标签: java scala packages scalac

这听起来很尴尬。我的目的是了解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命令中,我然后导航到dinnertime并使用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的经验有限,所以我已经请求scala大师在stackoverflow上帮助我理解发生了什么以及为什么? 这个嵌套包是否有理由由Scala而不是Java创建?

2 个答案:

答案 0 :(得分:5)

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

$ javac dinnertime/HelloWorld.java

$ scalac dinnertime/Dinner.scala

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

在程序包中运行编译器时会出现差异。结果javac足够聪明,可以将目标二进制文件放在根目录下,而不是当前的direcotyr。对于总是使用当前目录作为基础的scalac,情况并非如此。您可以使用-d参数:

轻松解决此问题
$ cd dinnertime
$ scalac -d .. Dinner.scala

答案 1 :(得分:5)

Tomasz explained要使其发挥作用所需的一切,请让我解释原因。

Scala并未强制要求源文件位于反映包的目录层次结构中。也就是说,Dinner.scala可以任何地方:它无关紧要。

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

很抱歉给予它如此重视,但是来自Java可能很难理解这一点。

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

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