类型'IpLoc选项'不包含字段'ip'

时间:2015-03-12 15:13:57

标签: f#

我有一个返回记录类型的函数,但编译器抱怨:

The type 'IpLoc option' does not contain a field 'ip'

该功能如下:

let validIp (list : IpRanges list) (ip:string) : option<IpLoc> =
     list
        |> Seq.pick (fun e -> 
            let range = IPAddressRange.Parse(e.ipStartEnd);

            match range.Contains(IPAddress.Parse(ip)) with
            | true -> Some({ip=ip; subnet=e.subnet; gateway=e.gateway})
            | false -> None
        )

类型是

type IpLoc =
     { ip : String
       subnet : String
       gateway : String }

我做错了什么?

1 个答案:

答案 0 :(得分:2)

函数Seq.pick返回第一个,其中提供的函数返回某个值。请参阅doc:https://msdn.microsoft.com/en-us/library/vstudio/ee353772(v=vs.100).aspx

例如:

let aseq = [ 'a'; 'b'; 'c' ]
let picked = aseq |> Seq.pick (fun e -> if e = 'b' then Some 42 else None)
> 
val picked : int = 42

因此,您的validIp函数返回类型IpLoc的值,而不是声明的Option<IpLoc>

更改功能类型或将返回值更改为选项类型,或使用返回选项值的类似签名的**Seq.tryPick**功能。

请注意,如果序列中没有提供函数返回某些值的元素,则Seq.pick会抛出异常(KeyNotFoundException)。

如果您需要返回IpLoc

let validIp (list : IpRanges list) (ip:string) : IpLoc =
     list
        |> Seq.pick (fun e -> 
            let range = IPAddressRange.Parse(e.ipStartEnd);

            match range.Contains(IPAddress.Parse(ip)) with
            | true -> Some({ip=ip; subnet=e.subnet; gateway=e.gateway})
            | false -> None
        )

如果您需要返回Option<IpLoc>

let validIpOption (list : IpRanges list) (ip:string) : Option<IpLoc> =
     list
        |> Seq.tryPick (fun e -> 
            let range = IPAddressRange.Parse(e.ipStartEnd);

            match range.Contains(IPAddress.Parse(ip)) with
            | true -> Some({ip=ip; subnet=e.subnet; gateway=e.gateway})
            | false -> None
        )