Null 值 (F#)
本主题介绍如何在 F# 中使用 null 值。
Null 值
Null 值在 F# 中通常不用于表示值或变量。 不过,在某些情况下,null 会显示为异常值。 如果类型是在 F# 定义的,则不允许将 null 用作常规值,除非已将 AllowNullLiteral 特性应用于该类型。 如果类型是在某种其他 .NET 语言中定义的,则 null 是可能值,并且,当您与此类类型进行互操作时,您的 F# 代码可能会遇到 null 值。
对于在 F# 中定义并严格地从 F# 中使用的类型,直接使用 F# 库创建 null 值的唯一方式是使用 Unchecked.defaultof 或 Array.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."