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

标签 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”?

最佳答案

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

the static initializer for the file is executed on first access of a value that has observable initialization

All definitions have observable initialization except for the following definitions in modules:

以下列表包括:

Non-mutable, non-thread-local values that are bound to a simple constant expression

注释掉第一行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;
}

关于f# - F# 模块初始化的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17575323/

相关文章:

f# - 与计算表达式的相互递归

f# - 你如何在 F# 中使用 IList<>?

f# - Intellisense 错误和 #I 与脚本文件

mysql - SQLProvider 不适用于任何数据库类型。没有来自 SqlTypeProvider [F#][macOS] 的类型

list - 将元组列表乘以 F# 中的元组

f# - 如何将 Seq.sum 用于任何 .Net 值类型?

F#:为 seq{} 生成的 IL 代码与其他计算工作流

neo4j - 在现有节点之间创建关系的更快方法?

F# WebApi 从可区分联合返回格式正确的 json

.net - 如何在 F# 中声明对象数组?