【问题标题】:Why is `System.Void` different from `unit` type?为什么 `System.Void` 与 `unit` 类型不同?
【发布时间】:2018-01-14 08:01:22
【问题描述】:

F# Types Docs 说:

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

说是相等,但是为什么下面的比较返回false呢?

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

【问题讨论】:

  • 我猜这是因为Sustem.Void 不能用作泛型类型的参数。这就是我们同时拥有TaskTask&lt;T&gt; 的原因,其中F# 允许我们只有Async&lt;'T&gt;
  • 阅读herethere
  • Equivalentequal 是不同的东西。

标签: .net f# functional-programming


【解决方案1】:

嗯,它们并不完全等同。您发布的报价有点误导。

F# 类型 unit 等同于 C# keyword void(不是类型 System.Void!)因为类型和关键字都用于声明不返回任何东西:

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

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

这就是您的报价所要说的,但等价就止于此了。

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

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

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

【讨论】:

    【解决方案2】:

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

    验证它:类型 = System.Void {程序集 = mscorlib,版本 = 4.0.0.0,文化 = 中性,PublicKeyToken = b77a5c561934e089; AssemblyQualifiedName = "System.Void, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

    这是单位:

    验证它:类型 = Microsoft.FSharp.Core.Unit {Assembly = FSharp.Core,版本=4.4.1.0,文化=中性,PublicKeyToken=b03f5f7f11d50a3a; AssemblyQualifiedName = "Microsoft.FSharp.Core.Unit, FSharp.Core, Version=4.4.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

    很明显,它们并不相同。有关更多信息,请参见 Wikipedia 例如。

    【讨论】:

    • 与问题无关,但如何打印类型的完整描述?
    • @MiP 你是什么意思?只需typedefof&lt;System.Void&gt; 或任何“T”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 2012-02-12
    • 2023-03-10
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多