导入声明:open
关键字
导入声明指定模块或命名空间,无需使用完全限定的名称即可引用其中的元素。
语法
open module-or-namespace-name
open type type-name
备注
每次使用完全限定的命名空间或模块路径来引用代码时,都可能会创建难以编写、读取和维护的代码。 相反,可以对经常使用的模块和名称空间使用 open
关键字,以便在引用该模块或命名空间的成员时,可以使用名称的缩写形式而不是完全限定名称。 此关键字类似于 C# 中的using
关键字、Visual C++ 中的 using namespace
和 Visual Basic 中的 Imports
。
提供的模块或命名空间必须在同一个项目中或在引用的项目或程序集中。 如果不是,可以添加对项目的引用,或使用 -reference
命令行选项(或其缩写 -r
)。 有关详细信息,请参阅编译器选项。
导入声明使得在声明之后的代码中,直至封闭的名称空间、模块或文件的末尾,名称都是可用的。
使用多个导入声明时,这些声明应显示在单独的行中。
下面的代码演示如何使用 open
关键字来简化代码。
// Without the import declaration, you must include the full
// path to .NET Framework namespaces such as System.IO.
let writeToFile1 filename (text: string) =
let stream1 = new System.IO.FileStream(filename, System.IO.FileMode.Create)
let writer = new System.IO.StreamWriter(stream1)
writer.WriteLine(text)
// Open a .NET Framework namespace.
open System.IO
// Now you do not have to include the full paths.
let writeToFile2 filename (text: string) =
let stream1 = new FileStream(filename, FileMode.Create)
let writer = new StreamWriter(stream1)
writer.WriteLine(text)
writeToFile2 "file1.txt" "Testing..."
当在多个打开的模块或命名空间中出现相同的名称而出现歧义时,F# 编译器不会发出错误或警告。 出现歧义时,F# 会优先选择最近打开的模块或命名空间。 例如,在下面的代码中,empty
表示 Seq.empty
,即使 empty
位于 List
和 Seq
模块中也是如此。
open List
open Seq
printfn %"{empty}"
因此,打开包含具有相同名称的成员的模块或命名空间(如 List
或 Seq
)时要小心;请考虑改用限定名称。 应避免代码依赖于导入声明的顺序的任何情况。
开放类型声明
F# 在如下类型上支持 open
:
open type System.Math
PI
这将公开该类型上所有可访问的静态字段和成员。
还可以使用 open
F# 定义的记录和可区分联合类型来公开静态成员。 对于可区分联合,还可以公开联合用例。 这对于访问你可能不想打开的模块内声明的类型中的联合用例很有帮助,如下所示:
module M =
type DU = A | B | C
let someOtherFunction x = x + 1
// Open only the type inside the module
open type M.DU
printfn "%A" A
仅使用 global
说明符从根路径打开
嵌套模块,比如
module A =
module B =
...
可以通过以下方式打开:
open A // opens A
open B // opens A.B
若要仅打开完全限定的模块或命名空间,请使用 global
说明符为它们添加前缀:
open global.A // works
open global.B // this now fails
open global.A.B // works
默认打开的命名空间
某些命名空间在 F# 代码中使用非常频繁,以至于不需要显式的导入声明就可以隐式打开它们。 下表显示了默认打开的命名空间。
命名空间 | 说明 |
---|---|
FSharp.Core |
包含内置类型(如 int 和 float )的基本 F# 类型定义。 |
FSharp.Core.Operators |
包含基本算术运算,如 + 和 * 。 |
FSharp.Collections |
包含不可变集合类,如 List 和 Array 。 |
FSharp.Control |
包含控件构造的类型,如迟缓计算和异步表达式。 |
FSharp.Text |
包含格式化 IO 的函数,例如 printf 函数。 |
AutoOpen 属性
如果要在引用某个程序集时自动打开命名空间或模块,可以将 AutoOpen
属性应用于该程序集。 还可以将 AutoOpen
属性应用于某模块,以在打开父模块或命名空间时自动打开该模块。 有关详细信息,请参阅 AutoOpenAttribute。
RequireQualifiedAccess 属性
某些模块、记录或联合类型可能会指定 RequireQualifiedAccess
属性。 引用这些模块、记录或联合的元素时,无论是否包含导入声明,都必须使用限定名称。 如果针对定义常用名称的类型策略性地使用此属性,则有助于避免名称冲突,从而使代码更能适应库中的更改。 有关详细信息,请参阅 RequireQualifiedAccessAttribute。