大家好!
我在Visual Studio Community 2017中使用F#进行脚本编写。我处理大型数据集,我经常使用recursvive函数循环。为了大致了解这需要多长时间,我目前正在使用printfn
来打印当前的迭代索引。虽然我猜这听起来很简单,但这是一个例子:
let foo f bar maxIter =
let rec loop currentIter resultList=
if currentIter<maxIter then
printfn "current Iteration: %i" currentIter
loop (currentIter+1) ((f bar)::resultList)
else
List.rev resultList
loop 0 []
这实际上是fsi窗口的混乱,如果我在更大的功能中在不同的步骤上另外打印其他字符串,则无法遵循。
我的问题如下:我能以某种方式用fsi更新当前迭代次数中的一行吗?我尝试过使用printf
和回车:
printf "%i\r"
但这与使用printfn的结果相同。
提前感谢您的帮助!
编辑:正如此线程上的评论者指出的那样,目前似乎无法在VS FSI中执行此操作。
答案 0 :(得分:2)
可以通过设置光标位置来实现(自包含)迭代计数器:
let rec progress i : unit =
printf "%i" i
System.Threading.Thread.Sleep 1000
System.Console.SetCursorPosition(0, System.Console.CursorTop)
progress (i+1)
progress 0
注1:这将覆盖当前行上的任何内容,即除非您实现某些同步方法或除了进度之外始终使用printfn
,否则将覆盖其他日志输出。可以通过以下方式观察到此行为:
open System
open System.Threading
let rec progress i p : unit =
printf "%s %i" p i
Thread.Sleep 1000
Console.SetCursorPosition(0, Console.CursorTop)
progress (i+1) p
Tasks.Task.Run(fun () -> progress 0 "t1")
Thread.Sleep 500
Tasks.Task.Run(fun () -> progress 0 "t2")
注意2:由于VS的限制,这在VisualStudio FSI中不起作用。它可以在VS Code,控制台(编译为EXE,运行CMD或PowerShell)或使用非VS FSI(在Windows 10,VS 15.5.1上测试)中工作。