簡體   English   中英

如何在F#中定義printfn等價物

[英]How to define printfn equivalent in F#

由於我使用F#進行研究(特別是使用F#interactive),我希望能夠切換“print-when-in-debug”功能。

我可以

let dprintfn = printfn

F#互動說

val dprintfn : (Printf.TextWriterFormat<'a> -> 'a)

我可以使用

dprintfn "myval1 = %d, other val = %A" a b

每當我想要我的腳本。

現在我想以不同的方式定義dprintfn ,這樣它就會忽略它的所有參數,但與printfn語法兼容。 怎么樣?


我想到的最接近(但不起作用)的變體是:

let dprintfn (arg: (Printf.TextWriterFormat<'a> -> 'a)) = ()

但它以下不編譯然后dprintfn "%A" "Hello" ,導致error FS0003: This value is not a function and cannot be applied

PS我目前使用Debug.WriteLine(...)的別名作為解決方法,但問題仍然是有趣的F#類型系統。

您可以使用kprintf函數,該函數使用標准語法格式化字符串,但隨后調用您指定的(lambda)函數來打印格式化的字符串。

例如,如果設置了debug ,則以下打印字符串,否則不執行任何操作:

let myprintf fmt = Printf.kprintf (fun str -> 
  // Output the formatted string if 'debug', otherwise do nothing
  if debug then printfn "%s" str) fmt

我一直在分析我的應用程序,發現調試格式化會導致嚴重的性能問題 由於應用程序的性質,幾乎每個代碼字符串都會發生調試格式化。
顯然,這是由kprintf引起的,它無條件地格式化然后將string傳遞給謂詞。
最后,我提出了以下可能對您有用的解決方案:

let myprintf (format: Printf.StringFormat<_>) arg =
    #if DEBUG 
        sprintf format arg
    #else
        String.Empty
    #endif

let myprintfn (format: Printf.TextWriterFormat<_>) arg =
    #if DEBUG
        printfn format arg
    #else
        ()
    #endif

用法很簡單,格式檢查工作正常:

let foo1 = myprintf "foo %d bar" 5
let foo2 = myprintf "foo %f bar" 5.0

// can't accept int
let doesNotCompile1 = myprintf "foo %f bar" 5
// can't accept two arguments
let doesNotCompile2 = myprintf "foo %f bar" 5.0 10

// compiles; result type is int -> string
let bar = myprintf "foo %f %d bar" 5.0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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