这听起来很尴尬。我的目的是了解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创建?
答案 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
参数进行更改。