2014-01-21 95 views
1

我有以下脚本。Map.tryFind返回null而不是无

type SetCookie = { 
    NameValue : string * string; 
    Domain : string option; 
    Path : string option; 
    Expires : string option; 
    MaxAge : string option; 
    Secure : bool; // ? no associated value, anything better than bool 
    HttpOnly : bool; // ? no associated value, anything better than bool 
    } 

let GetCookie str = 
    let allkeyvalues = 
     str.Split ';' 
     |> Array.map (fun str -> 
      match str.Split '=' with 
      | [| key |] -> (key.Trim(), "") 
      | [| key; value |] -> (key.Trim(), value) 
      | _ -> failwith "there's more than one '='; the format is incorrect.") 
    let namevalue = allkeyvalues.[0] 
    let attributes = 
     Seq.skip 1 allkeyvalues 
     |> Seq.map (fun (key, value) -> 
      (key.ToLower(), value)) // attribute names are case-insensitive 
     |> Map.ofSeq 
    { 
     NameValue = namevalue 
     Domain = Map.tryFind "domain" attributes 
     Path = Map.tryFind "path" attributes 
     Expires = Map.tryFind "expires" attributes 
     MaxAge = Map.tryFind "maxage" attributes 
     Secure = Map.containsKey "secure" attributes 
     HttpOnly = Map.containsKey "httponly" attributes 
    } 

然而,函数调用

GetCookie "XXX=YYY; path=/" 

返回null DomainExpires ....和所有其他选项类型,而不是无。根据文件,如果没有找到它应该返回None。 http://msdn.microsoft.com/en-us/library/ee353538.aspx

{NameValue = 
    ("XXX", "YYY"); 
    Domain = null; 
    Path = Some "/"; 
    Expires = null; 
    MaxAge = null; 
    Secure = false; 
    HttpOnly = false;} 

回答

7

的F#None值实际上由.NET null表示。在这种情况下,您会以通用的方式打印出来,但在其他情况下只是一种表示细节。你可以通过注释一个与CompilationRepresentationFlags.UseNullAsTrueValue没有任何参数的联合案例来为自己的歧视工会实际得到这种行为。

3

的F#规范规定None使用null表示:

5.4.8 NULL的含量

类型使用null作为表示值。这些类型不允许 空字面值,但使用空值作为表示。

对于这些类型,使用null文字不是直接允许的 。然而,该类型的“正常”值中的一个或全部是由空值表示的 。以下类型是本 类别中:

具有 Microsoft.FSharp.Core.CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue) 属性标志和单空工会情况下的任何联合类型。空值代表 这种情况。特别是,在F#选项< _> 类型中,null表示无。