在F#中,你如何理解接受可变数量参数的函数?
我有这样的代码......(日志功能只是一个例子,确切的实现并不重要)
let log (msg : string) =
printfn "%s" msg
log "Sample"
在整个代码中使用sprintf格式化字符串调用它,例如
log (sprintf "Test %s took %d seconds" "foo" 2.345)
我想在日志功能中讨论sprintf功能,看起来像......
logger "Test %s took %d seconds" "foo" 2.345
我尝试过像
这样的东西let logger fmt ([<ParamArray>] args) =
log (sprintf fmt args)
但我无法弄清楚如何将ParamArray参数传递给sprintf调用。
如何在F#中完成?
答案 0 :(得分:7)
let log (s : string) = ()
let logger fmt = Printf.kprintf log fmt
logger "%d %s" 10 "123"
logger "%d %s %b" 10 "123" true
答案 1 :(得分:6)
printf
的行为 - 就像F#中的函数一样,在某种程度上是特殊的。它们采用格式字符串,指定预期参数是什么。您可以使用desco所示的Printf.kprintf
来定义您自己的带有格式字符串的函数,但不能更改格式字符串的处理。
如果你想做一些像C#params
(其中参数的数量是可变的,但不依赖于格式字符串),那么你可以直接在成员上使用ParamArray
属性:
open System
type Foo =
static member Bar([<ParamArray>] arr:obj[]) =
arr |> Seq.mapi (fun i v -> printfn "[%d]: %A" i v)
然后你可以使用任意数量的参数调用Foo.Bar
而不使用格式字符串:
Foo.Bar("hello", 1, 3.14)
这对字符串格式不太优雅,但在其他情况下可能很有用。不幸的是,它只适用于成员(而不是使用let
定义的函数)