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