繁体   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