我需要在我想通过利用do
块来完成的模块中进行一些设置。奇怪的是,我的do
街区似乎从未被击中。
更奇怪的是,如果我将模块代码加载到 fsi 中,它确实会受到影响。这是我的例子:
主文件
[<EntryPoint>]
let main args =
printfn "%b" TestNamespace.M.x
0
测试模块.fs
namespace TestNamespace
module M =
do
printfn "In do"
failwith "Error" // this is line 6
let x = true
当我运行编译的可执行文件时,我得到
>test.exe
true
为什么没有抛出异常?如果我自己在 FSI 中运行模块,我会得到
In do
System.Exception: Error
at <StartupCode$FSI_0006>.$FSI_0006.main@() in C:\Projects\Personal2\Playground\fsscripts\fsscripts\TestModule.fs:line 6
Stopped due to error
所以它得到了例外。
我在反编译中看到 do 初始化程序被滚动到一个单独的类中
namespace \u003CStartupCode\u0024fsscripts\u003E
{
internal static class \u0024Library1
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[CompilerGenerated]
[DebuggerNonUserCode]
internal static int init\u0040;
static \u0024Library1()
{
ExtraTopLevelOperators.PrintFormatLine<Unit>((PrintfFormat<Unit, TextWriter, Unit, Unit>) new PrintfFormat<Unit, TextWriter, Unit, Unit, Unit>("In do"));
Operators.FailWith<Unit>("Error");
bool x = M.x;
}
}
}
VS 实际的模块代码:
namespace TestNamespace
{
[CompilationMapping(SourceConstructFlags.Module)]
public static class M
{
public static bool x
{
[DebuggerNonUserCode] get
{
return true;
}
}
}
}
那么如何确保 do 块实际执行?
--
编辑,鉴于上面的示例算作一个简单的常量表达式,因此不会产生可观察的初始化,为什么以下也不起作用?
[<EntryPoint>]
let main args =
printfn "%d" (TestNamespace.M.x id 1)
0
namespace TestNamespace
module M =
do
printfn "In do"
failwith "Error"
let x f a = f a
这打印出来1
没有问题。
编辑,在重新阅读 Tomas 的评论后,因为函数被认为是一个常量表达式。