[英]Why don't I see results of printfn called outside the main entrypoint (F#)
我有一個F#控制台應用程序,該應用程序調用其他模塊中的函數以從主函數入口點執行其工作。 在其他功能中,我還有一系列的printfn
可以為我提供有關程序運行的信息。
在DEBUG模式下編譯時,所有語句都將打印到控制台。 但是,在RELEASE模式下編譯時,僅打印到控制台的唯一語句是直接在主入口點函數內部的語句。
我該怎么做才能在其他模塊中打印信息聲明?
下面提供了一個代碼示例:
Program.fs
[<EntryPoint>]
let main argv =
printfn "%s" "start" // prints in RELEASE and DEBUG mode
File1.Run
printfn "%s" "end" // prints in RELEASE and DEBUG mode
System.Console.ReadLine() |> ignore
0 // return an integer exit code
File1.fs
module File1
let Run =
let x = 1
printfn "%d" x // this won't print in RELEASE mode
是的,你是(正確的)-它不會打印,因為Run
在這里是一個表達式,似乎編譯器正在釋放模式下對其進行優化。
為什么不呢? 在一個完美(純凈/參照透明)的世界中,您有一個unit
類型的表達式,該表達式只能有一個值()
...,甚至不使用或記住該值!
老實說,我不知道這是錯誤還是功能;)
無論如何,這個簡單的技巧將對您有所幫助,實際上,您不應該像以前那樣使用帶有效果的表達式:
let Run () =
let x = 1
printfn "%d" x
...
File1.Run ()
看到了-現在它是一個函數,在正確的時間調用get,並且輸出返回;)
順便說一句:如果您對這種東西感興趣,您可以使用Reflector之類的工具(目前我手頭還沒有),或者僅使用IL DASM (VS還是應該安裝該工具)-如果您查看已編譯的調試/發布程序集,您會發現沒有類似這樣的地方:
IL_001f: call class [FSharp.Core]Microsoft.FSharp.Core.Unit File1::get_Run()
如果使用表達式,則可以在發行版中找到。
我玩了一點,您必須發揮創造力,以使編譯器執行以下操作:
例如
let reallyNeed v =
if v = ()
[<EntryPoint>]
let main argv =
printfn "%s" "start" // prints in RELEASE and DEBUG mode
File1.Run |> reallyNeed
printfn "%s" "end" // prints in RELEASE and DEBUG mode
System.Console.ReadLine () |> ignore
0 // return an integer exit code
可以(打印您的1
)-同時
ignore File1.Run
要么
let reallyNeed v = ignore v
不要`);-似乎您必須在某處實際使用該值:D
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.