【问题标题】:F# equivalent of C# operator/symbol "?."F# 等效于 C# 运算符/符号“?”。
【发布时间】:2019-07-06 02:23:46
【问题描述】:

我有以下 f# 代码

product.code <- productPage.Html
    .Descendants["li"]
    .Select(fun node -> node.InnerText())
    .Where(fun link -> (Regex.Match(link,@"code:").Success))
    .FirstOrDefault()
    .Replace("code:", "")
    .Trim()

我在处理空值时遇到了一些问题。 在 c# 中我会做这样的事情。

product.code = productPage?.Html
    ?.Descendants["li"]
    ?.Select(node => node.InnerText())
    ?.Where(link => Regex.Match(link,@"code:").Success)
    ?.FirstOrDefault()
    ?.Replace("code:", "")
    ?.Trim() ?? "Not Found"

这可能吗?

【问题讨论】:

  • 在 F# 中,productPage 本身应该是 Option&lt;Page&gt; 或任何类型,而不是 null。选项has members Option.map,option.iter。你用的是哪个库?它是否返回空值或选项?也许有一个 F# 包装器或替代品?
  • 类似于 F# 数据包中的 HtmlParser
  • @Spaceman 也许,也许不是。你检查过 HtmlParser 吗?答案是首先避免空值。你用的是哪个库?您可以使用例如productPage.Html |&gt; Option.map page-&gt;... 而不是检查空值

标签: f#


【解决方案1】:

在第二个例子中,它看起来像“?”。由于其初始使用,必须通过整个调用链进行。与其尝试重新创建此运算符并保​​留其在 C# 中的外观,我建议您使用更惯用的 F#。例如:

module String =
    let replace (oldValue: string) (newValue: string) (s: string) =
        s.Replace (oldValue, newValue)

    let trim (s: string) =
        s.Trim()

let result =
    match isNull productPage with
    | true -> None
    | false ->
        productPage.Html.Descendants.["li"]
        |> Seq.map (fun node -> node.InnerText())
        |> Seq.tryPick (fun link -> (Regex.Match (link, "code:").Success))

let code =
    match result with
    | Some html -> 
        html
        |> String.replace "code:" ""
        |> String.trim
    | None -> "Not Found" 

product.code <- code

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 2012-11-28
    • 2011-08-09
    • 2019-02-11
    • 2011-03-30
    • 2012-12-29
    • 2018-01-02
    相关资源
    最近更新 更多