do
ブロックを活用して達成したかったモジュールでセットアップを行う必要があります。奇妙なことに、私のdo
ブロックはヒットしないようです。
さらに奇妙なことに、モジュール コードを fsi にロードすると、ヒットします。これが私の例です:
Main.fs
[<EntryPoint>]
let main args =
printfn "%b" TestNamespace.M.x
0
TestModule.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のコメントを再読した後、編集してください。