3

FSC は、必要がなくても毎回私の .scala ファイルを再コンパイルします。試行の間に何も編集せずに 2 回コンパイルでき、それらを再コンパイルします! たとえば、2つのファイルがあります

Hello.scala

class Hello{
  print("hello")
}

そして Tokens.scala:

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 にプロジェクトを最初からコンパイルするように依頼すると、次の出力が表示されます。

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 コンパイルを依頼します。

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 の場合は愚かに動作します。問題は何らかの形で継承に関連していると思いますが、それだけです。

では、何が問題なのですか?

4

2 に答える 2

5

ベース名に一致するクラス ファイルがないため、Tokens.scala が再コンパイルされます。つまり、Tokens.class ファイルは生成されません。ソース ファイルをコンパイルする必要があるかどうかを判断するとき、 fsc は同じベース名を持つクラスファイルを探します。クラス ファイルが存在しない場合、またはソース ファイルの変更時刻がクラス ファイルの変更時刻より遅い場合、ソース ファイルは再構築されます。 . 可能であれば、 Simple Build Toolを調べることをお勧めします。その継続的なコンパイル モードは、source->classfile マッピングを正確に追跡し、Tokens.scala を再コンパイルしません。

さらに笑いを誘うために、別のソース ファイルが含まれている場合にコンパイラがどのように動作するかを考えてみてくださいclass Tokens

scala では、任意のソース ファイルで任意のパブリック クラス/オブジェクトを使用できますが、Java の規則にある程度従い、ファイル内にソース ファイルのベース名と同じ名前のクラス/オブジェクトが少なくとも 1 つあることを前提とするツールがまだかなりあります。

于 2010-09-27T14:14:11.747 に答える
4

他の人が書いたものを投稿するのはあまり好きではありませんが、この質問は厳密に尋ねられたものよりも完全な回答に値すると思います.

したがって、まず、fscデフォルトですべてを再コンパイルします。ファイル名がクラス名と一致するため、省略されているのはantではなくです。コンパイル済みと呼ばれるクラスがないため、除外されていません。つまり、 a がない場合、再コンパイルされました。fscHello.scalaTokens.scalaTokensTokens.classTokens.scala

それは Scala で行うのは間違っています。Scala は、Java とは 1 つの基本的な側面で異なります。JVM の技術的な制限により、 を変更すると、traitそれを使用するすべてのクラス、オブジェクト、またはインスタンス化の再コンパイルが必要になります。

これで、タスクを修正してant、Scala 2.8 から始めて、よりスマートなことを行うことができます。この情報は、Netbeans の名声のための Scala プラグインの Caoyuan によるblogtrader.netから取得しています。以下のように、ビルド ターゲットで Scala タスクを定義します。

<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 ターゲットを変更する必要があります。これは、Scala が他のクラスを再コンパイルするために必要なためです。次のようになります。

<path id="build.classpath">
    <pathelement location="${scala-library.jar}"/>
    <pathelement location="${scala-compiler.jar}"/>
    <pathelement location="${build.classes.dir}"/>
</path>

詳細については、Caoyuan のブログを参照してください。

于 2010-09-27T14:49:39.720 に答える