簡體   English   中英

為什么在主入口點(F#)之外看不到printfn的結果

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM