首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FSC每次都会重新编译

FSC每次都会重新编译
EN

Stack Overflow用户
提问于 2010-09-27 20:20:25
回答 2查看 721关注 0票数 3

FSC每次都会重新编译我的.scala文件,即使没有必要-我可以在两次尝试之间不编辑任何东西的情况下编译它,它会重新编译它们!例如,我有两个文件

Hello.scala

代码语言:javascript
复制
class Hello{
  print("hello")
}

和Tokens.scala:

代码语言:javascript
复制
abstract class Token(val str: String, val start: Int, val end: Int)
  {override def toString = getClass.getSimpleName + "(" + "[" + start + "-" + end + "]" + str + ")"}
class InputToken(str: String, start: Int, end: Int)
        extends Token(str, start, end)
 class ParsedToken(str: String, start: Int, end: Int, val invisible: Boolean)
        extends Token(str, start, end)

当我要求ant从头开始编译项目时,我看到了以下输出:

代码语言:javascript
复制
ant compile
init:
    [mkdir] Created dir: D:\projects\Test\build\classes
    [mkdir] Created dir: D:\projects\Test\build\test\classes

compile:
      [fsc] Base directory is `D:\projects\Test`
      [fsc] Compiling source files: somepackage\Hello.scala, somepackage\Tokens.scala to D:\projects\Test\build\classes

BUILD SUCCESSFUL

然后我不编辑任何东西,并再次要求ant编译:

代码语言:javascript
复制
ant compile
init:
    [mkdir] Created dir: D:\projects\Test\build\classes
    [mkdir] Created dir: D:\projects\Test\build\test\classes

compile:
      [fsc] Base directory is `D:\projects\Test`
      [fsc] Compiling source files: somepackage\Tokens.scala to D:\projects\Test\build\classes

BUILD SUCCESSFUL

正如您所看到的,fsc在Hello.scala (不需要重新编译)的情况下表现得很聪明,而在Tokens.scala的情况下则表现得很愚蠢。我认为这个问题在某种程度上与继承有关,但仅此而已。

那么到底出了什么问题呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-09-27 22:49:40

我不太喜欢别人写的帖子,但我认为这个问题值得一个比严格的问题更完整的答案。

因此,首先,默认情况下,fsc会重新编译所有内容。它是ant,而不是fsc,因为文件名与类名匹配,所以没有使用Hello.scala。它没有遗漏Tokens.scala,因为没有编译名为Tokens的类--因此,在没有Tokens.class的情况下,它重新编译了Tokens.scala

这是用Scala做的错误的事情。Scala与Java的一个基本区别在于,由于Java虚拟机的技术限制,trait中的更改需要重新编译使用它的每个类、对象或实例化。

现在,可以修复ant任务,从Scala2.8开始做更聪明的事情。我从blogtrader.net上摘录了这个信息,作者是Netbeans的Scala插件的曹元。在build目标上定义Scala任务,如下所示:

代码语言:javascript
复制
<scalac srcdir="${src.dir}"
        destdir="${build.classes.dir}"
        classpathref="build.classpath"
        force="yes"
        addparams="-make:transitive -dependencyfile ${build.dir}/.scala_dependencies"
        >
    <src path="${basedir}/src1"/> 
    <!--include name="compile/**/*.scala"/-->
    <!--exclude name="forget/**/*.scala"/-->
</scalac>

它会告诉ant重新编译所有内容,因为ant根本不够聪明,无法确定哪些内容需要重新编译。它还告诉Scala构建一个包含编译依赖项的文件,并使用传递依赖项算法来确定哪些内容需要重新编译。

您还需要更改init目标以将build目录包含在build类路径中,因为Scala将需要该目录来重新编译其他类。它应该看起来像这样:

代码语言:javascript
复制
<path id="build.classpath">
    <pathelement location="${scala-library.jar}"/>
    <pathelement location="${scala-compiler.jar}"/>
    <pathelement location="${build.classes.dir}"/>
</path>

更多详情,请参考草源博客。

票数 4
EN

Stack Overflow用户

发布于 2010-09-27 22:14:12

Tokens.scala被重新编译,因为没有与其基名匹配的类文件。也就是说,它不会生成Tokens.class文件。在决定是否编译源文件时,fsc会查找具有相同基名的类文件,如果类文件不存在或源文件的修改时间晚于类文件的修改时间,则重新构建源文件。如果可以,我建议您研究一下Simple Build Tool,它的连续编译模式可以准确地跟踪源代码->类文件映射,并且不会重新编译Tokens.scala

为了获得额外的乐趣,考虑一下如果您有一个不同的源文件,其中包含class Tokens,编译器可能会做什么。

尽管scala允许在任何源文件中使用任意的公共类/对象,但仍然有相当多的工具假定您在某种程度上遵循java约定,并且在文件中至少有一个类/对象的名称与源文件的基名相同。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3803672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档