Null 值
本主题介绍如何在 F# 中使用 null 值。
空值
在 F# 中,null 值通常不用于值或变量。 但是,在某些情况下,null 显示为异常值。 如果在 F# 中定义了类型,则不允许将 null 作为常规值,除非将 AllowNullLiteral 属性应用于该类型。 如果某个类型是用其他 .NET 语言定义的,则 null 是一个可能的值,并且当你与此类类型进行互操作时,你的 F# 代码可能会遇到 null 值。
对于在 F# 中定义并严格从 F# 中使用的类型,直接使用 F# 库创建空值的唯一方法是使用 Unchecked.defaultof 或 Array.zeroCreate。 但是,对于从其他 .NET 语言中使用的 F# 类型,或者如果将该类型与不是用 F# 编写的 API(例如 .NET Framework)一起使用,则可能会出现 null 值。
如果可以在另一种 .NET 语言中使用具有可能为 null 值的引用变量,则可以在 F# 中使用 option
类型。 如果没有对象,则可以使用选项值 option
,而不是使用 F# None
类型的 null。 如果有对象,则可将选项值 Some(obj)
用于对象 obj
。 有关详细信息,请参阅选项。 请注意,如果对于 Some x
,x
恰好是 null
,则仍然可以将 null
值打包到选项中。 因此,在值为 None
时使用 null
非常重要。
null
关键字是 F# 中的有效关键字,当使用 .NET Framework API 或使用以另一种 .NET 语言编写的其他 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 值,例如使用 Array.zeroCreate
调用 Unchecked.defaultof
。 必须谨慎处理此类代码,使 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."