为什么'printf“%A”无”输出null

问题描述 投票:3回答:2

为什么printfSome x输出Some x,但为<null>输出None

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

> printfn "%A" None;;
<null>
val it : unit = ()
f# optional
2个回答
5
投票

在编译后的代码中,F#使用null值表示Noneoption<'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()失败)。据推测,打印可以使用静态类型信息以这种方式获取类型信息-但实现起来可能会比较棘手。


4
投票

这实际上是较旧的行为,不会消失。 Tomas的答案对于较旧的FSI是正确的,但是如果您安装较新的版本(例如.NET Core 3.1最新版本或.NET 5预览版),则在示例中您会看到dotnet fsi表示None格式为None

© www.soinside.com 2019 - 2024. All rights reserved.