通过


可以为 null 的值类型

Nullable<'T>表示也可以是的任何null类型。 在与出于效率原因可能选择使用 null 值表示这些类型(例如整数)的库和组件交互时,这很有帮助。 支持此构造的基础类型是 System.Nullable<T>

语法

Nullable<'T>
Nullable value

声明并赋值

声明一个可为空的值类型就像在 F# 中声明任何类似包装器的类型:

open System

let x = 12
let nullableX = Nullable<int> x

还可以省略泛型类型参数并允许类型推理来解析它:

open System

let x = 12
let nullableX = Nullable x

若要为可为空的值类型赋值,还需要显式赋值。 对于 F# 定义的可为空的值类型,不存在隐式转换:

open System

let mutable x = Nullable 12
x <- Nullable 13

赋值 null

无法直接将 null 赋值给可为空的值类型。 请改用 Nullable()

let mutable a = Nullable 42
a <- Nullable()

这是因为 Nullable<'T> 未将 null 用作正确的值。

传递并赋值给成员

使用成员和 F# 值之间的主要区别在于,在使用成员时可以隐式推断可为空的值类型。 考虑以下将可为空的值类型作为输入的方法:

type C() =
    member _.M(x: Nullable<int>) = x.HasValue
    member val NVT = Nullable 12 with get, set

let c = C()
c.M(12)
c.NVT <- 12

在上面的示例中,可以将 12 传递给 M 方法。 还可以将 12 赋值给自动属性 NVT。 如果可以将输入构造为可为空的值类型并且它与目标类型匹配,则 F# 编译器将隐式转换此类调用或赋值。

检查可为空的值类型实例

Options(用于表示可能值的通用结构)不同,可为空的值类型不与模式匹配一起使用。 相反,需要使用 if 表达式并检查 HasValue 属性。

若要获取基础值,请在 Value 检查后使用 HasValue 属性,如下所示:

open System

let a = Nullable 42

if a.HasValue then
    printfn $"{a} is {a.Value}"
else
    printfn $"{a} has no value."

可以为 null 的运算符

对可为空的值类型的运算(例如算术或比较)可能需要使用可为空的运算符

可以使用 FSharp.Linq 命名空间中的转换运算符从一个可为空的值类型转换为另一个可为空的值类型:

open System
open FSharp.Linq

let nullableInt = Nullable 10
let nullableFloat = Nullable.float nullableInt

还可以使用不可为空的相应运算符转换为基元类型,如果该类型没有值,则会产生异常:

open System
open FSharp.Linq

let nullableFloat = Nullable 10.0
let standardFloat = float nullableFloat

printfn $"value is %f{float standardFloat}"

还可以使用可为空的运算符作为检查 HasValueValue 的快捷方式:

open System
open FSharp.Linq

let nullableInt = Nullable 10
let nullableFloat = Nullable.float nullableInt

let isBigger = nullableFloat ?> 1.0
let isBiggerLongForm = nullableFloat.HasValue && nullableFloat.Value > 1.0

?> 比较检查左侧是否可为空,并且仅当它有值时才成功。 它等效于它后面的行。

另请参阅