为什么 'printf "%A" None' 输出 null

Sim*_*gan 3 f# optional

为什么printf输出Some xfor Some x,但是<null>for None

> printfn "%A" (Some 123);;
Some 123
val it : unit = ()

> printfn "%A" None;;
<null>
val it : unit = ()
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 5

在编译后的代码中,F# 使用null值来表示为了效率的None情况option<'T>。您实际上可以通过使用CompilationRepresentationFlags. UseNullAsTrueValue编译标志(请参阅MSDN 文档)将相同的用于您自己的可区分联合。

您可以通过使用该Object.ReferenceEquals方法看到这是怎么回事:

> let n = None;;
val n : 'a option

> System.Object.ReferenceEquals(n, null);;
val it : bool = true
Run Code Online (Sandbox Code Playgroud)

为什么printfn "%A"只打印内部表示而不是认识到这实际上代表了None情况?

我认为答案是打印是使用反射动态完成的,因此参数只是obj在某个时候转换为类型的值。一旦你有一个nulltype的值obj,就不可能在转换之前恢复它是什么类型,所以你无法找到null实际代表的类型None(因为null.GetType()失败)。据推测,打印可以使用静态类型信息以这种方式获取类型信息 - 但这可能更难以实现。