记录可以有一个可以为空的字段吗?

use*_*480 3 f#

具有可以为空的字段的记录是合法的,例如:

type MyRec = { startDate : System.Nullable<DateTime>; }
Run Code Online (Sandbox Code Playgroud)

这个例子确实构建在我的项目中,但如果它是合法的,这是一个好的做法,如果有什么问题,这会引入什么?

Gus*_*Gus 7

这是合法的,但F#鼓励使用选项类型:

type MyRec = { startDate : option<DateTime>; }
Run Code Online (Sandbox Code Playgroud)

通过使用选项,您可以轻松地对选项和其他操作进行模式匹配,以转换选项值,例如地图值(通过使用Option.map)和抽象,例如Maybe monad(使用Option.bind),而使用nullable则不能,因为只有值类型可以成为无懈可击的.

您会注意到大多数F#函数(例如List.choose)使用选项而不是nullables.某些语言功能(如可选参数)被解释为F#选项类型.

但是在某些情况下,当您需要与C#交互时,您可能希望使用Nullable.

当使用Linq查询数据库时,您可以考虑使用Linq.Nullable模块Nullable运算符


Cod*_*nda 5

F# 不允许在 F# 中声明的类型为 null。但是,如果您使用 F# 中未定义的类型,您仍然可以使用 null。这就是为什么您的代码仍然合法。这是互操作性所必需的,因为您可能需要将 null 传递给 .NET 库或接受它作为结果。

但我想说这不是一个好的做法,除非您特别需要互操作性。正如其他人指出的,您可以使用选项功能。但是,这不会创建可选记录字段,您在创建该字段时无需指定其值。要创建记录类型的值,您仍然需要提供可选字段的值。

此外,您可以使用AllowNullLiteral 属性标记类型,F# 编译器将允许 null 作为该特定类型的值,即使它是在 F# 中声明的类型。但AllowNullLiteral 不能应用于记录类型。

哦,我差点忘了提:选项类型与可为 null 的类型不兼容。我天真地期望能起作用的东西(愚蠢的我!)。有关详细信息,请参阅这个很好的 SO 讨论