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

时间:2018-01-14 08:01:22

标签: .net f# functional-programming

  

F# Types Docs说:

     

Unit Type:描述unit类型,一种具有一个值并由()表示的类型;相当于C#中的void和Visual Basic中的Nothing

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

typedefof<System.Void> = typedefof<unit>;;
val it : bool = false

2 个答案:

答案 0 :(得分:11)

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

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

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

// C#
void f( int x ) { ... }

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

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

类型System.Void完全是一个不同的动物:它只是为了支持反射而存在,但void相同,System.Int32的方式是与int相同。

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

答案 1 :(得分:0)

它们相似但不一样。但是编译器将使用unit参数编译一个函数作为void函数。单位是函数式编程中的一种特殊类型,与void不同。此外,你不应该对返回false的比较感到惊讶,因为这是无效的:

  

val it:Type = System.Void       {Assembly = mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089;        AssemblyQualifiedName =“System.Void,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089”;

这是单位:

  

val it:Type = Microsoft.FSharp.Core.Unit       {Assembly = FSharp.Core,Version = 4.4.1.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a;        AssemblyQualifiedName =“Microsoft.FSharp.Core.Unit,FSharp.Core,Version = 4.4.1.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a”;

很明显他们不一样。有关详情,请参阅Wikipedia