为什么printf
为Some x
输出Some x
,但为<null>
输出None
?
> printfn "%A" (Some 123);;
Some 123
val it : unit = ()
> printfn "%A" None;;
<null>
val it : unit = ()
在编译后的代码中,F#使用null
值表示None
的option<'T>
情况以提高效率。实际上,您可以通过使用CompilationRepresentationFlags.
UseNullAsTrueValue
编译标志(请参阅MSDN documentation)将其用于您自己的已区分联合。
您可以通过使用Object.ReferenceEquals
方法看到这是怎么回事:
> let n = None;; val n : 'a option > System.Object.ReferenceEquals(n, null);; val it : bool = true
为什么
printfn "%A"
仅打印内部表示而不是识别出它实际上表示None
情况?
[我认为答案是,打印是使用反射来动态完成的,因此在某些时候,参数仅被转换为类型为obj
的值。一旦具有类型null
的值obj
,就无法恢复在转换前的类型,因此您将无法发现null
实际上代表了None
(因为null.GetType()
失败)。据推测,打印可以使用静态类型信息以这种方式获取类型信息-但实现起来可能会比较棘手。
这实际上是较旧的行为,不会消失。 Tomas的答案对于较旧的FSI是正确的,但是如果您安装较新的版本(例如.NET Core 3.1最新版本或.NET 5预览版),则在示例中您会看到dotnet fsi
表示None
格式为None
。