F#将none传递给函数,将null作为参数值

时间:2012-05-03 15:58:19

标签: .net f#

这真的很奇怪,我担心我做了一些愚蠢的事,但我无法理解。

我将None作为第一个参数传递给函数some但是当函数执行时,parentNode的值为null(我不关心它打印null对于None,函数参数值IS为null None)。我最终在打印功能行上得到一个空引用错误,因为parentNode为null。我试图改变args并改变顺序,但这没有帮助。我有一种潜在的怀疑,认为这与卷曲有关,但我不知所措......

我不得不用公司问题的空字符串替换真实的网址值,但如果有帮助则是xsd的网址

以下是代码:

#light
open System
open System.Xml
open System.Net
open System.Collections.Generic

type StartResult =
    | Parameters of XsdParserParameters
    | Xsd of Xsd

and Xsd(text) =
    let rows = new List<string>()

    member this.Text
        with get() = text

    member this.Rows
        with get() = rows

and XsdParserParameters() =
    let mutable url = ""

    member this.Url
        with get() = url
        and set(value) = url <- value

    member this.Start() =
        try
            use client = new WebClient()
            let xsd = client.DownloadString(this.Url)
            StartResult.Xsd(Xsd(xsd))
        with e ->
            StartResult.Parameters(this)

let processor () =
    let parameters = XsdParserParameters()
    parameters.Url <- ""
    match parameters.Start() with
    | StartResult.Parameters(xpparams) ->
        //some error
        ()
    | StartResult.Xsd(xsd) ->

        let rec some (parentNode : XmlNode option) (node : XmlNode) =
            let a = ()

            for subNode in node.ChildNodes do
                match subNode.LocalName with
                | "complexType" ->
                    xsd.Rows.Add(
                        sprintf
                            "%O~%s~%d~%d~%s~%s~%O" 
                            parentNode 
                            subNode.Value 
                            1 
                            1 
                            (subNode.Attributes.GetNamedItem("name").Value)
                            "" 
                            false)
                    some (Some(subNode)) subNode 
                | "sequence" ->
                    some parentNode subNode 
                | "element" ->
                    xsd.Rows.Add(
                        sprintf 
                            "%O~%s~%d~%d~%s~%s~%O" 
                            parentNode 
                            subNode.Value 
                            1 
                            1 
                            (subNode.Attributes.GetNamedItem("name").Value) 
                            "" 
                            false)
                    some (Some(subNode)) subNode 
                | _ ->
                    ()

        let xdoc = new XmlDocument();
        xdoc.LoadXml(xsd.Text)

        some (None) (xdoc.DocumentElement)

processor()

printfn "Done..."
Console.ReadLine() |> ignore

2 个答案:

答案 0 :(得分:4)

不幸的是,这是F#打印None的方式:

> sprintf "%O" None;;
val it : string = "<null>"

您可以轻松为sprintf类型编写自定义option函数,例如:

let sprintOption v = 
    if Option.isNone v then "None" else sprintf "%A" v

答案 1 :(得分:4)

Option<'T>source on Github)使用属性[<CompilationRepresentation([CompilationRepresentationFlags.UseNullAsTrueValue)>],该属性导致在运行中由None表示的无效案例(null) -time。