Null 值 (F#)

本主题介绍如何在 F# 中使用 null 值。

Null 值

Null 值在 F# 中通常不用于表示值或变量。 不过,在某些情况下,null 会显示为异常值。 如果类型是在 F# 定义的,则不允许将 null 用作常规值,除非已将 AllowNullLiteral 特性应用于该类型。 如果类型是在某种其他 .NET 语言中定义的,则 null 是可能值,并且,当您与此类类型进行互操作时,您的 F# 代码可能会遇到 null 值。

对于在 F# 中定义并严格地从 F# 中使用的类型,直接使用 F# 库创建 null 值的唯一方式是使用 Unchecked.defaultofArray.zeroCreate。 但是,对于从其他 .NET 语言中使用的 F# 类型,或者,如果您通过未以 F# 编写的 API(例如 .NET Framework)使用该类型,则可能会出现 null 值。

当您可能将引用变量与其他 .NET 语言中可能的 null 值一起使用时,您可以使用 F# 中的 option 类型。 在没有对象的情况下,对于 F# option 类型,您可以使用选项值 None,而不是使用 null。 在存在对象的情况下,可将选项值 Some(obj) 用于对象 obj。 有关更多信息,请参见选项 (F#)

null 关键字是 F# 语言中的有效关键字,并且,当您使用以其他 .NET 语言编写的 .NET Framework API 或其他 API 时,必须使用该关键字。 在以下两种情况下,您可能需要 null 值:调用 .NET API 并传递 null 值作为实参时,以及解释来自 .NET 方法调用的返回值或输出形参时。

若要将 null 值传递到 .NET 方法,只需在调用代码中使用 null 关键字。 下面的代码示例阐释了这一点。

open System

// Pass a null value to a .NET method.
let ParseDateTime (str: string) =
    let (success, res) = DateTime.TryParse(str, null, System.Globalization.DateTimeStyles.AssumeUniversal)
    if success then
        Some(res)
    else
        None

若要解释从 .NET 方法中获得的 null 值,请尽可能使用模式匹配。 下面的代码示例演示如何使用模式匹配来解释 ReadLine 尝试读取超出输入流末尾的内容时返回的 null 值。

// Open a file and create a stream reader.
let fileStream1 =
    try
        System.IO.File.OpenRead("TextFile1.txt")
    with 
        | :? System.IO.FileNotFoundException -> printfn "Error: TextFile1.txt not found."; exit(1)

let streamReader = new System.IO.StreamReader(fileStream1)

// ProcessNextLine returns false when there is no more input;
// it returns true when there is more input.
let ProcessNextLine nextLine =
    match nextLine with
    | null -> false
    | inputString ->
        match ParseDateTime inputString with
        | Some(date) -> printfn "%s" (date.ToLocalTime().ToString())
        | None -> printfn "Failed to parse the input."
        true

// A null value returned from .NET method ReadLine when there is
// no more input.
while ProcessNextLine (streamReader.ReadLine()) do ()

F# 类型的 null 值也可以采用其他方式生成,例如,使用调用了 Unchecked.defaultof 的 Array.zeroCreate。 您必须小心处理此类代码,以将 null 值保持为封装状态。 在仅适用于 F# 的库中,您不必检查每个函数中是否有 null 值。 如果编写与其他 .NET 语言进行互操作的库,则可能必须添加针对 null 输入参数的检查,并引发 ArgumentNullException,就像在 C# 或 Visual Basic 代码中所做的一样。

可使用下列代码检查任意值是否为 null。

match box value with
| null -> printf "The value is null."
| _ -> printf "The value is not null."

请参见

参考

match 表达式 (F#)

其他资源

值 (F#)