如何在匹配模式中创建记录

How to create record in match pattern

我想编写一个从 xml 文件中读取 ip 地址的应用程序。该文件看起来像

<range>
    <start>192.168.40.1</start>
    <end>192.168.50.255</end>
    <subnet>255.255.255.0</subnet>
    <gateway>192.168.50.1</gateway>
</range>

我创建一个记录类型来保存 ip 地址

type Scope = { Start: IPAddress; End: IPAddress; Subnetmask: IPAddress; Gateway: IPAddress } 

我写了一个单元函数,输出 ip。

loc
            |> Seq.iter (fun e -> match e.Name.LocalName with
                                    |"start" -> printfn "Start %s" e.Value
                                    |"end" -> printfn "End %s" e.Value
                                    |"subnet" -> printfn "Subnet %s" e.Value
                                    |"gateway" -> printfn "Gateway %s" e.Value
                                    | _ -> ())

如何return范围记录类型而不是单位?

如评论中所述,XML type provider 使这变得容易得多。您可以将它指向一个示例文件,它会推断出结构并让您轻松阅读文件:

type RangeFile = XmlProvider<"sample.xml">
let range = RangeFile.Load("file-you-want-to-read.xml")

let scope = 
  { Start = IPAddress.Parse(range.Start)
    End = IPAddress.Parse(range.End)
    Subnetmask = IPAddress.Parse(range.Subnet)
    Gateway = IPAddress.Parse(range.Gateway) }

也就是说,您当然也可以自己实现。您编写的代码是一个好的开始 - 有多种方法可以做到这一点,但无论如何,您需要根据元素的本地名称进行一些查找(以查找开始、结束等) .

一个选项是将所有属性加载到字典中:

let lookup = 
   loc
   |> Seq.map (fun e -> e.Name.LocalName, IPAddress.Parse(e.Value)
   |> dict

现在您有一个包含每个键的 IPAddress 的查找 table,因此您可以使用以下方法创建 Scope 值:

let scope = 
  { Start = lookup.["start"]; End = lookup.["end"];
    Subnetmask = lookup.["subnet"]; Gateway = lookup.["gateway"] }

也就是说,XML 类型提供程序的好处在于它消除了根据字符串值进行查找的需要,因此您不太可能犯错字造成的错误。