F#模块初始化的不同行为

时间:2013-07-10 15:52:38

标签: f#

我有以下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”不再打印?

1 个答案:

答案 0 :(得分:17)

我认为规范的第12.5.1节Execution of Static Initializers有你的答案。引用相关位:

  

文件的静态初始化程序在首次访问具有可观察初始化值的值时执行

  

除模块中的以下定义外,所有定义都具有可观察的初始化:

以下列表包括:

  

绑定到简单常量表达式的非可变非线程局部值

在评论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;
}