15

在 F# 的口头禅中,似乎本能地避免了null,Nullable<T>及其同类。作为交换,我们应该改用选项类型。老实说,我真的看不出有什么区别。

  • 我对 F# 选项类型的理解是,它允许您指定一个可以包含其任何正常值的类型,或者None. 例如,除了 之外,an 还Option<int>允许 an 可以具有的所有值。intNone

  • 我对 C# 可空类型的理解是,它允许您指定一个可以包含其任何正常值的类型,或者null. 例如,除了. 之外, Nullable<int>aka还int?允许 an 可以具有的所有值。intnull

有什么不同?Nullable用and Option, nulland做一些词汇替换None,你基本上有同样的事情。有什么大惊小怪的null

4

6 回答 6

21

F# 选项是通用的,您可以Option<'T>为任何类型创建'T

Nullable<T>是一种非常奇怪的类型;您只能将其应用于结构,虽然该Nullable类型本身就是一个结构,但它不能应用于自身。所以你不能创造Nullable<Nullable<int>>,而你可以创造Option<Option<int>>。他们必须做一些框架魔术才能使其适用于Nullable. 无论如何,这意味着对于 Nullables,您必须先验地知道类型是类还是结构,如果是类,您只需要使用 null 而不是 Nullable。这是一个丑陋的泄漏抽象;它的主要价值似乎在于数据库互操作,因为我猜在数据库域中处理“int,或无值”对象是很常见的。

我认为,.Net 框架在涉及 null 和 .Net 时简直是一团糟Nullable。您可以争辩说 F# 通过具有 '增加了混乱' Option,或者通过建议您避免 null/ Nullable(除非对于互操作绝对必要)并专注于使用Options. 你可以找到有两种观点的人。

你可能还想看看

没有 null 的语言的最佳解释

于 2012-06-21T21:33:00.433 回答
7

有什么不同?

F# 允许您选择是否希望您的类型成为一种option类型,并且当您这样做时,鼓励您检查并在类型中明确None存在或不存在。None

C# 强制每个引用类型允许null并且不鼓励您检查null.

所以这只是默认值的差异。

用 Nullable 和 Option、null 和 None 做一些词汇替换,你基本上得到了同样的东西。null 有什么大惊小怪的?

正如 SML、OCaml 和 Haskell 等语言所展示的那样,删除null可以从真实代码中移除大量运行时错误。以至于原创者null甚至将其描述为他的“十亿美元错误”。

于 2012-06-22T15:13:44.987 回答
7

因为每个 .NET 引用类型都可以有这个额外的、无意义的值——无论它是否null,这种可能性都存在,你必须检查它——而且因为Nullable使用null它表示“无”,我认为它使很多消除所有怪异(F# 所做的)并要求明确“无”的可能性是有意义的。Option<_>这样做。

于 2012-06-21T22:14:14.987 回答
4

使用的优点option是它明确表示变量不能包含任何值,而可为空的类型使其隐含。给定如下定义:

string val = GetValue(object arg);

类型系统没有记录 val 是否可以为空,或者如果 arg 为空会发生什么。这意味着需要在函数边界进行重复检查,以验证调用者和被调用者的假设。

除了模式匹配,还可以静态检查使用选项类型的代码,以确保两种情况都得到处理,例如以下代码会导致警告:

let f (io: int option) = function
| Some i -> i
于 2012-06-21T21:34:39.697 回答
2

正如 OP 所提到的,在传达可选类型时使用单词optionalnullable之间没有太大的语义差异。

null当您想要表达可选类型时,内置系统的问题变得很明显。

在 C# 中,所有引用类型都可以是 null. 所以,如果我们依靠内置null来表达可选值,所有的引用类型都被迫是可选的……不管开发者是否有意。开发人员无法指定非可选引用类型(直到 C# 8)。

所以,问题不在于null. 问题是null被引用类型劫持了。

作为一名 C# 开发人员,我希望我可以使用内置null系统来表达可选性。这正是 C# 8 对可空引用类型所做的。

于 2019-08-28T00:31:21.823 回答
0

嗯,一个区别是,对于 a Nullable<T>, T 只能是一个结构,它可以显着减少用例。

另请务必阅读此答案:https ://stackoverflow.com/a/947869/288703

于 2012-06-21T21:16:04.113 回答