F#中模块和命名空间之间的差异

时间:2011-02-12 09:52:52

标签: .net f# namespaces module

我在理解F#中的模块和命名空间之间的确切区别以及使用其中一个时遇到了问题。 好吧,它们都被认为是为了填充代码并定义层次结构以使我们的项目井井有条。

模块有许多功能:它们可以包含值,各种类型,也可以定义这些元素publicprotectedinternal

但是,在使用模块时?

我也理解模块最终被映射为MSIL(中间语言)中的类。所以模块是一个类,是一个类型.... 我怀疑的程度有所改善......

使用模块时??? 它们有用吗?

d。 Syme还认为模块是可扩展的,所以我认为从这个角度来看它们就像命名空间一样。

我无法理解使用它们的原因。

三江源

2 个答案:

答案 0 :(得分:9)

一个主要区别:

.Net名称空间不能容纳(让定义),而模块可以。

在IL / Bytecode级别,模块被编译为.net类,而不是.net名称空间。

何时使用模块?

对于一个小而具体的任务,F#和其他FP通常遵循自下而上编程的模式:将任务分解为一组小函数,然后将这些函数分组到一个模块中。

答案是,使用模块将一组相关函数和其他F#值和类型组合在一起是如此自然。

虽然命名空间用于分组更大的东西:例如Matrix操作的所有类。

模块不是静态类(在C#意义上) 模块可以保存特殊的F#值,例如咖喱功能;虽然静态类不能。

答案 1 :(得分:6)

正如尹朱所说,模块可以保持价值。您可以打开名称空间等模块。这两个特征在一起就是为什么在F#中你可以做像

这样的事情
let z = max x y

而在像C#这样的语言中,你总是要说出像

这样的东西
var z = Math.Max(x,y)
//      ^^^^^   can't call methods from elsewhere without a qualifier

并使用限定名称(SomeClass.Method)而不仅仅是名称(letBoundFunction)。因此,当您希望人们能够打开模块Foo并通过在任何地方说bar而不是bar来致电Foo.bar时,您可以使用模块。 (这对于运营商尤其有用,例如,如果您在库中定义了一堆用户定义的运算符(例如+++或诸如此类),通过将它们放在模块中,人们可以打开模块然后使用例如x +++ y而不是像(Foo.+++) x y或其他任何繁琐的东西。)

请注意,虽然默认情况下F#将代码放在模块中的.fs文件中(带有文件名),但您可以通过将文件中的第一个代码作为名称空间声明来更改它,例如

namespace Yadda
// declare some types or whatnot, they go in namespace Yadda

或通过声明自己的模块

module Blah
// stuff goes in Blah module

位于文件顶部。