F#:为什么选项类型与可为空类型不兼容? [英] F#: Why aren't option types compatible with nullable types?
问题描述
为什么像int option"这样的选项类型与像Nullable"这样的可空类型不兼容?
Why aren't option types like "int option" compatible with nullable types like "Nullable"?
我认为这种差异存在某种语义原因,但我不知道那是什么.
I assume there is some semantic reason for the difference, but I can't figure what that is.
当值可能存在或不存在时,使用 F# 中的选项.一个选项有一个基础类型,可能持有该类型的值,也可能没有值.
An option in F# is used when a value may or may not exist. An option has an underlying type and may either hold a value of that type or it may not have a value.
http://msdn.microsoft.com/en-us/library/dd233245%28VS.100%29.aspx
这听起来确实像 Nullable 结构.
That sure sounds like the Nullable structure.
推荐答案
因为 System.Nullable<'T>
的运行时表示选择.
Because of the runtime representation choice for System.Nullable<'T>
.
Nullable 尝试通过空指针表示值的缺失,并通过指向这些值的指针呈现值.
Nullable tries to represent the absent of values by the null pointer, and present values by pointers to those values.
(new System.Nullable<int>() :> obj) = null
|> printfn "%b" // true
(new System.Nullable<int>(1) :> obj).GetType().Name
|> printfn "%s" // Int32
现在考虑字符串.不幸的是,字符串可以为空.所以这是有效的:
Now consider strings. Unfortunately, strings are nullable. So this is valid:
null : string
但是现在 null
运行时值是不明确的 - 它可以指不存在值或存在 null
值.因此,.NET 不允许构造 System.Nullable
.
But now a null
runtime value is ambiguous - it can refer to either the absence of a value or a presence of a null
value. For this reason, .NET does not allow constructing a System.Nullable<string>
.
对比:
(Some (null : string) :> obj).GetType().Name
|> printfn "%s" // Option`1
话虽如此,我们可以定义一个双射:
That being said, one can define a bijection:
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)
如果您观察类型,这些函数将 'T
约束为一个结构并具有零参数构造函数.因此,也许 F# 编译器可以通过将其替换为 Option<'T where 'T : struct and 'T : (new : unit -> 'T)>
,并在必要时插入转换函数..
If you observe the types, these functions constrain 'T
to be a structure and have a zero-argument constructor. So perhaps F# compiler could expose .NET functions receiving/returning Nullable<'T>
by substituting it for an Option<'T where 'T : struct and 'T : (new : unit -> 'T)>
, and inserting the conversion functions where necessary..
这篇关于F#:为什么选项类型与可为空类型不兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!