为什么`System.Void`与`unit`类型不同?

MiP*_*MiP 4 .net f# functional-programming

F#Types Docs说:

单位类型:描述unit类型,具有一个值并由()表示的类型; 相当于void在C#和NothingVisual Basic中.

它说它们是平等的,但为什么以下比较会返回错误?

typedefof<System.Void> = typedefof<unit>;;
val it : bool = false
Run Code Online (Sandbox Code Playgroud)

Fyo*_*kin 12

嗯,他们并不是真的相同.你发布的报价有点误导.

F#类型unit等同于C#关键字 void(不是类型System.Void!),因为类型和关键字都用于声明不返回任何内容的函数:

// F#
let f (x:int) : unit = ...

// C#
void f( int x ) { ... }
Run Code Online (Sandbox Code Playgroud)

这就是你的引言所说的,但等价就在那里停止了.

在C#void中并不是真正的类型.它是一个用于声明无返回方法的关键字,但你不能在类型位置使用它 - 例如你不能有void变量,参数,类型参数等.这就是为什么我们有一个单独的委托Action而不是仅使用Func<void>.

这种类型System.Void完全是一种不同的动物:它的存在只是为了支持反射,但它一样void,方式System.Int32也是一样的int.

另一方面,在F#中,类型unit大多只是常规类型,与其他类型一样.它甚至在标准库中有一个定义.是的,编译器确实在某些特殊情况下给它一些特殊处理,但这仅用于优化和互操作,在语言级别是不可见的.因此,unit可用于任何类型的位置 - 参数,变量等等.这意味着,例如,对于不返回任何内容的函数,F#不需要特殊的函数类型,它可以使用int -> unit.