导入声明:
导入声明指定一个模块或命名空间,可以在不使用完全限定名称的情况下引用其元素。
语法
open module-or-namespace-name
open type type-name
注解
每次都可以使用完全限定的命名空间或模块路径来引用代码,从而创建难以写入、读取和维护的代码。 相反,可以将 open
关键字用于常用模块和命名空间,以便在引用该模块或命名空间的成员时,可以使用名称的短形式而不是完全限定的名称。 此关键字类似于 using
C# 中的关键字、 using namespace
Visual C++ 和 Imports
Visual Basic 中的关键字。
提供的模块或命名空间必须位于同一项目或引用的项目或程序集中。 如果没有,可以添加对项目的引用,或使用-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
位于模块Seq
List
和模块中也是如此。
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# 代码中频繁使用,无需显式导入声明即可隐式打开这些命名空间。 下表显示了默认打开的命名空间。
Namespace | DESCRIPTION |
---|---|
FSharp.Core |
包含内置类型的基本 F# 类型定义,例如 int 和 float 。 |
FSharp.Core.Operators |
包含基本的算术运算,例如 + 和 * 。 |
FSharp.Collections |
包含不可变的集合类,例如 List 和 Array 。 |
FSharp.Control |
包含控件构造的类型,例如延迟计算和异步表达式。 |
FSharp.Text |
包含格式化 IO 的函数,例如 printf 函数。 |
AutoOpen 属性
如果要在引用程序集时自动打开命名空间或模块,则可以将 AutoOpen
属性应用于程序集。 还可以将 AutoOpen
属性应用于模块,以在打开父模块或命名空间时自动打开该模块。 有关详细信息,请参阅 AutoOpenAttribute。
RequireQualifiedAccess 属性
某些模块、记录或联合类型可以指定 RequireQualifiedAccess
属性。 引用这些模块、记录或联合的元素时,无论是否包括导入声明,都必须使用限定的名称。 如果在定义常用名称的类型上以策略方式使用此属性,则有助于避免名称冲突,从而使代码对库中的更改更具弹性。 有关详细信息,请参阅 RequireQualifiedAccessAttribute。