10

次の F# プログラムがあります。

open MyModule

printfn "%d" test

MyModule の場合:

module MyModule

printfn "foo"

let test = 
  printfn "bar"
  42

これにより、次の出力が生成されます。

foo
bar
42

MyModule を次のように変更すると:

module MyModule

printfn "foo"

let test = 
  // printfn "bar" <-- note the comment!
  42

...結果は次のとおりです。

42

「foo」が出力されなくなったのはなぜですか?

4

1 に答える 1

18

仕様のセクション 12.5.1、Execution of Static Initializersに答えがあると思います。関連するビットを引用する:

ファイルの静的初期化子は、監視可能な初期化を持つ値の最初のアクセス時に実行されます

モジュール内の次の定義を除いて、すべての定義には観察可能な初期化があります。

次のリストは次のとおりです。

単純な定数式にバインドされた、変更不可でスレッド ローカルでない値

の1行目をコメントアウトするtestと定数式になります。そのため、静的初期化をトリガーしなくなりました。

編集

この仕様では、この動作の根拠は示されていませんが、C# のものと似ています。たとえば、次のコードでは静的初期化は発生しません。

class Program {
    static void Main(string[] args) {
        Console.WriteLine(T.Integer);
        Console.WriteLine(T.Null);
        Console.WriteLine(T.Enum);
        Console.Read();
    }
}

static class T {
    static T() {
        Console.WriteLine("You won't see this.");
    }
    public const int Integer = 1;
    public const string Null = null;
    public const ConsoleKey Enum = ConsoleKey.Escape;
}
于 2013-07-10T16:08:08.417 に答える