我开始学习F#,并且我注意到C#语法的一个主要区别在于,类型推断的使用远远多于C#中的类型推理。这通常是F#的一个好处。为什么将类型推断表示为好处?类型推断的好处是什么?
想象一下,您有一个类层次结构和使用不同类的代码。强大的打字功能可以让您快速检测出在任何方法中使用哪些类。 通过类型推断,它不会如此明显,您必须使用提示来了解使用哪个类。是否有任何技术可以通过类型推断使F#代码更具可读性?
我开始学习F#,并且我注意到C#语法的一个主要区别在于,类型推断的使用远远多于C#中的类型推理。这通常是F#的一个好处。为什么将类型推断表示为好处?类型推断的好处是什么?
想象一下,您有一个类层次结构和使用不同类的代码。强大的打字功能可以让您快速检测出在任何方法中使用哪些类。 通过类型推断,它不会如此明显,您必须使用提示来了解使用哪个类。是否有任何技术可以通过类型推断使F#代码更具可读性?
这个问题假设您在F#中使用面向对象的编程(例如复杂的类层次结构)。虽然您当然可以这样做,但使用OO概念主要用于互操作性或在.NET库中包装某些F#功能。
理解代码。当您在函数样式中编写代码时,类型推断变得更有用。它使代码更短,但也有助于你理解正在发生的事情。例如,如果你写在名单map
功能(在LINQ的Select
法):
let map f list =
seq { for el in list -> f el }
的类型推断告诉你该函数的类型是:
val map : f:('a -> 'b) -> list:seq<'a> -> seq<'b>
这我们的预期相符一下我们想写 - 参数f
是转弯'a
类型的值到'b
类型的值的功能和map
函数需要'a
值的列表,并产生'b
值的列表。因此,您可以使用类型推断来轻松检查您的代码是否符合您的期望。
推广。自动泛化(在注释中提到)意味着上面的代码自动尽可能重用。在C#中,你可能会这样写:
IEnumerable<int> Select(IEnumerable<int> list, Func<int, int> f) {
foreach(int el in list)
yield return f(el);
}
这种方法不通用的 - 它是Select
是仅适用于int
值的集合。但是没有理由将其限制为int
- 相同的代码适用于任何类型。类型推断机制可以帮助你发现这样的概括。
更多的检查。最后,归功于推理,如果您必须明确编写所有类型,F#语言可以更轻松地检查更多的事情。这适用于语言的许多方面,但它使用的度量单位最好的证明:
let l = 1000.0<meter>
let s = 60.0<second>
let speed = l/s
F#编译器推断speed
有型float<meter/second>
- 它知道如何衡量工作的单位和推断的类型包括单元信息。这个功能非常有用,但如果你必须手动编写所有单元(因为类型变长),这将很难使用。一般来说,您可以使用更精确的类型,因为您不必(始终)键入它们。
感谢您提供详细的答案,特别是关于自动泛化的解释 - 我不知道这个功能。 – eternity
这是一个广泛的问题@eternity。也许你可以编辑你的问题更具体一些? –