F#:为什么不';t选项类型是否与可空类型兼容?

F#:为什么不';t选项类型是否与可空类型兼容?,f#,null,F#,Null,为什么像“int option”这样的选项类型与像“nullable”这样的可空类型不兼容 我想这种差异是有语义上的原因的,但我不知道那是什么 当值可能存在或可能不存在时,使用F#中的选项。期权具有基础类型,可能持有该类型的值,也可能没有值 这听起来确实像是可为空的结构。关键区别在于必须测试选项类型,以查看它是否有值。关于它的语义,请参见这个问题:同样,这是我有限的理解,但问题可能在于如何在IL中呈现每一个。“nullable”结构的处理方式可能与选项类型略有不同 您将发现,各种.Net语言之

为什么像“int option”这样的选项类型与像“nullable”这样的可空类型不兼容

我想这种差异是有语义上的原因的,但我不知道那是什么

当值可能存在或可能不存在时,使用F#中的选项。期权具有基础类型,可能持有该类型的值,也可能没有值


这听起来确实像是可为空的结构。

关键区别在于必须测试选项类型,以查看它是否有值。关于它的语义,请参见这个问题:

同样,这是我有限的理解,但问题可能在于如何在IL中呈现每一个。“nullable”结构的处理方式可能与选项类型略有不同


您将发现,各种.Net语言之间的交互实际上归结为IL的呈现方式。大多数时候,它工作得很好,但有时会引起问题。(). 就在您认为信任抽象级别是安全的时候。:)

这两者有不同的语义。举个例子,Nullable是一个幂等数据构造函数,它只对值类型有效,而option是一个普通的泛型类型。所以你不能有一个

Nullable<Nullable<int>>
Nullable
但是你可以有一个

option<option<int>>
选项

通常,尽管存在一些重叠的场景,但也可以使用其中一个场景执行某些操作,而不能使用另一个。

因为
System.Nullable]的运行时表示选择=
如果a.HasValue那么
a.价值观
其他的
没有一个
设nullableOfOption=函数
|None->new System.Nullable()
|一些x->新系统。可为空(x)

如果观察这些类型,这些函数将
'T
约束为一个结构,并具有零参数构造函数。因此,也许F#编译器可以公开.NET函数接收/返回
Nullable'T)>
,并在必要时插入转换函数..

,那又怎样?您可以在语言语法级别提出该要求,但在运行时级别仍然使用null。在运行时级别,它们使用null表示。不幸的是,您错了。您不需要检查选项类型以查看它们是否有值,您可以直接调用option.value并希望不会出现异常。如果不使用模式匹配,编译器甚至不会发出警告。@Jonathan:最好测试选项类型,这就是它的使用方法。提供对值的直接访问是为了方便,但应避免使用它。提供一种方便的方法,然后告诉人们不要使用它,这与.NET API设计的“成功陷阱”理念不符。这解释了为什么不能使用Nullable作为选项的运行时表示形式。这并不能解释为什么不能让特例选项与Nullable兼容。这样的特例在我看来并不可取。你为什么想要optionF的某些实例?它已经充满了奇怪的特殊情况。例如,接受值或空值的“字符串”和接受值或无值的“字符串选项”之间有什么区别?@JonathanAllen令人困惑的是,你可以有一个
string选项
,其值为
Some null
。这不是真的
Nullable
是一个结构,因此,它的null值不能由null指针表示。相反,C#编译器的特殊情况是
Nullable
类型,允许您使用null文本;这当然不同于允许变量持有空指针。可空结构有一个“has value”布尔字段;C#编译器将与null文本的比较转换为对HasValue属性的调用。运行时还特别处理装箱操作,这就是第一个示例按预期工作的原因。请稍候。正是
选项
表示空指针没有值。如果您查找Option.None的定义,它实际上就是
null
(new System.Nullable<int>() :> obj) = null
|> printfn "%b" // true

(new System.Nullable<int>(1) :> obj).GetType().Name
|> printfn "%s" // Int32
null : string
(Some (null : string) :> obj).GetType().Name
|> printfn "%s" // Option`1
let optionOfNullable (a : System.Nullable<'T>) = 
    if a.HasValue then
        Some a.Value
    else
        None

let nullableOfOption = function
    | None -> new System.Nullable<_>()
    | Some x -> new System.Nullable<_>(x)