因为我做的研究与F#(尤其是使用F#的互动),我想有切换的“打印时,在调试”功能。
我可以
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(...)
作为变通,但问题仍然是understading 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