在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)
但我无法弄清楚如何通过对sprintf的调用传递的ParamArray参数。
这是如何在F#中做了什么?
let log (s : string) = ()
let logger fmt = Printf.kprintf log fmt
logger "%d %s" 10 "123"
logger "%d %s %b" 10 "123" true
的行为printf
样的功能在F#是在某些方面特殊。 他们采取一个格式字符串,它指定了预期的论点是什么。 您可以使用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
)