如何将"字符串"转换为"option <string>"

Jon*_*len 7 f#

我有一个声明为的函数

let GetLength (value : option<string>) = 
    if value.IsSome then value.Value.Length else 0
Run Code Online (Sandbox Code Playgroud)

我有变量

let a : string = "tom"
Run Code Online (Sandbox Code Playgroud)

如何将a传递给GetLength函数?

Ste*_*ing 11

接受的答案不会编译,并产生......

GetLength Some a;;
Run Code Online (Sandbox Code Playgroud)

^^^^^^^^^^^^^^错误FS0003:此值不是函数,无法应用

F#认为您正在构建一个(GetLength Some)应用于该值的函数a.那是因为它是一种功能语言.

正确的形式是

GetLength (Some a);;
Run Code Online (Sandbox Code Playgroud)


Zif*_*fre 8

你没有施展它.您需要使用Some构造函数:

GetLength Some a
Run Code Online (Sandbox Code Playgroud)

  • @Grauenwolf:在批评过于严厉之前,花一些时间学习如何编写惯用的F#代码可能是值得的.我想你会发现虽然它经常与典型的C#或VB.NET代码不同,但事情的设计原因却是...... (8认同)
  • @Grauenwolf:嗯,一个原因是,如果你不尝试应用自动转换,类型推断会容易得多.F#也不会自动从int转换为long,即使它是一个安全的扩展转换,原因是相同的.在Some构造函数中包装你的值有多难?对我而言,类型推断和一致性的权衡是非常值得的.我认为这是一个特殊的功能,"字符串选项"类型没有特别处理,我可以自己创建一个类似的类型,并让它以完全相同的方式工作. (3认同)

dah*_*byk 5

括号的替代方法:

GetLength <| Some a
Run Code Online (Sandbox Code Playgroud)

我认为解决这个问题很重要:

当你在一条线上使用12个令牌得到完全相同的东西时,为什么有人会愿意输入超过3行的18个令牌呢?

编写代码不仅仅是简洁性 - 它还涉及可读性和可维护性.假设你需要处理的情况anull.通过模式匹配,你可以从这个:

let GetLength (value : string option) =
    match value with
    | Some s -> s.Length
    | _ -> 0
Run Code Online (Sandbox Code Playgroud)

对此:

let GetLength (value : string option) =
    match value with
    | Some s when s <> null -> s.Length
    | _ -> 0
Run Code Online (Sandbox Code Playgroud)

对于F#程序员来说,意思是明确的.要修复您的实现,看起来像这样:

let GetLength (value : option<string>) = 
    if value.IsSome && value.Value <> null then value.Value.Length else 0
Run Code Online (Sandbox Code Playgroud)

结果可能是相同的,但我发现一眼就看出发生的事情并不容易.

如果模式匹配不会与您产生共鸣,那就没问题,但是随着逻辑的发展,简单情况下的额外"成本"通常会被多次补偿.