F#中有默认参数吗?

Nic*_*ick 5 f#

我编写了一个程序,将文件大小从字节转换为F#中的人类可读格式:

let rec sizeFmt num i =
    let suffix="B"
    let unit = ["";"Ki";"Mi";"Gi";"Ti";"Pi";"Ei";"Zi"]
    match abs num with
        | x when x < 1024.0 -> printfn "%3.1f %s%s" num unit.[i] suffix
        | _ -> sizeFmt (num / 1024.0) (i+1)

let humanReadable n =
    sizeFmt (float n) 0   
Run Code Online (Sandbox Code Playgroud)

运行示例:

> humanReadable 33;;
33.0 B
val it : unit = ()
> humanReadable 323379443;;
308.4 MiB
val it : unit = ()
> 
Run Code Online (Sandbox Code Playgroud)

题:

  1. 如果我可以i=0在函数中设置为默认值,那将是很好的 sizeFmt.我检查了F#文档,发现没有默认参数.所以我必须编写一个包装函数 humanReadable.有没有更好的办法?

  2. 为了同时处理int和float类型一样输入humanReadable 123;;humanReadable 123433.33;;,我一定要添加float n在包装功能.显而易见的问题是:它很容易超过最大int尺寸2,147,483,647.我猜可能有更好的方法,有吗?

Dan*_*iel 6

如果sizeFmt仅使用humanReadable,则使其成为内部函数是有意义的.这避免了"参数默认"问题.

此外,标记外部函数inline会使其接受n支持显式转换的任何类型float.

let inline humanReadable n =
    let rec sizeFmt num i =
        let suffix="B"
        let unit = ["";"Ki";"Mi";"Gi";"Ti";"Pi";"Ei";"Zi"]
        match abs num with
            | x when x < 1024.0 -> printfn "%3.1f %s%s" num unit.[i] suffix
            | _ -> sizeFmt (num / 1024.0) (i+1)
    sizeFmt (float n) 0   

humanReadable 123 //works
humanReadable 123433.33 //also works
Run Code Online (Sandbox Code Playgroud)


Tim*_*ers 4

一个可能有帮助的 F# 约定是将主要参数放在参数列表的末尾,将次要参数放在前面 - 与 OO 语言中的约定相反。这可以让您将主要参数传递给函数,例如

let rec sizeFmt i num =
   ...

123.0 |> sizeFmt 0
Run Code Online (Sandbox Code Playgroud)

它还可以让您轻松创建填充了可选参数的部分函数:

let humanReadable = sizeFmt 0
Run Code Online (Sandbox Code Playgroud)

在回答2时,不,没有更好的方法,除非你使sizeFmt泛型并传入类型值,1024.0但这可能不会使它变得更简单。