命名空间 (F#)
通过使用命名空间,可以为程序元素的分组附加名称,从而将代码组织到相关的功能区域中。
namespace [parent-namespaces.]identifier
备注
如果要将代码放置到某个命名空间中,则文件中的第一个声明必须是声明该命名空间。然后,整个文件的内容将成为该命名空间的组成部分。
命名空间不能直接包含值和函数。而必须将值和函数包括在模块中,然后将模块包括在命名空间中。命名空间可以包含类型和模块。
既可以使用 namespace 关键字显式声明命名空间,也可以在声明模块时隐式声明命名空间。若要显式声明一个命名空间,请使用 namespace 关键字并后跟相应的命名空间名称。以下示例演示的代码文件声明了一个命名空间 Widgets,并在其中包括一个类型和一个模块。
namespace Widgets
type MyWidget1 =
member this.WidgetName = "Widget1"
module WidgetsModule =
let widgetName = "Widget2"
如果文件的全部内容都位于一个模块中,则还可以通过使用 module 关键字并在完全限定的模块名称中提供新的命名空间名,来隐式声明命名空间。以下示例演示的代码文件声明了一个命名空间 Widgets 和一个模块 WidgetsModule(其中包含一个函数)。
module Widgets.WidgetModule
let widgetFunction x y =
printfn "%A %A" x y
下面的代码与上面的代码等效,但模块是局部模块声明。在这种情况下,命名空间必须单独占用一行。
namespace Widgets
module WidgetModule =
let widgetFunction x y =
printfn "%A %A" x y
如果相同文件中的一个或多个命名空间需要多个模块,则必须使用局部模块声明。当使用局部模块声明时,不能在模块声明中使用限定的命名空间。以下代码演示包含一个命名空间声明和两个局部模块声明的文件。在这种情况下,模块直接包含在命名空间中;不存在与该文件的名称相同的隐式创建的模块。该文件中的任何其他代码(如 do 绑定)都位于命名空间中,而不在内部模块中,因此,您需要通过使用模块名称来限定模块成员 widgetFunction。
namespace Widgets
module WidgetModule1 =
let widgetFunction x y =
printfn "Module1 %A %A" x y
module WidgetModule2 =
let widgetFunction x y =
printfn "Module2 %A %A" x y
module useWidgets =
do
WidgetModule1.widgetFunction 10 20
WidgetModule2.widgetFunction 5 6
此示例的输出如下所示。
Module1 10 20
Module2 5 6
有关更多信息,请参见模块 (F#)。
嵌入的命名空间
当创建嵌套的命名空间时,必须对其进行完全限定。否则,将会新建一个顶级命名空间。在命名空间声明中将忽略缩进。
下面的示例演示如何声明嵌套的命名空间。
namespace Outer
// Full name: Outer.MyClass
type MyClass() =
member this.X(x) = x + 1
// Fully qualify any nested namespaces.
namespace Outer.Inner
// Full name: Outer.Inner.MyClass
type MyClass() =
member this.Prop1 = "X"
文件和程序集中的命名空间
命名空间可以跨单个项目或编译中的多个文件。术语“命名空间片段”描述包含在一个文件中的部分命名空间。命名空间还可以跨多个程序集。例如,System 命名空间包含整个 .NET Framework,而后者又跨多个程序集并包含许多嵌套的命名空间。
全局命名空间
使用预定义命名空间 global 将名称放在 .NET 顶级命名空间中。
namespace global
type SomeType() =
member this.SomeMember = 0
还可使用 global 来引用顶级的 .NET 命名空间以(举例来说)解决与其他命名空间的名称冲突。
global.System.Console.WriteLine("Hello World!")