导入声明: open 关键字

导入声明指定一个模块或命名空间,可以在不使用完全限定名称的情况下引用其元素。

语法

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位于模块SeqList和模块中也是如此。

open List
open Seq
printfn %"{empty}"

因此,在打开模块或命名空间(如ListSeq或包含具有相同名称的成员)时要小心;相反,请考虑使用限定的名称。 应避免任何代码依赖于导入声明顺序的情况。

打开类型声明

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# 类型定义,例如 intfloat
FSharp.Core.Operators 包含基本的算术运算,例如 +*
FSharp.Collections 包含不可变的集合类,例如 ListArray
FSharp.Control 包含控件构造的类型,例如延迟计算和异步表达式。
FSharp.Text 包含格式化 IO 的函数,例如 printf 函数。

AutoOpen 属性

如果要在引用程序集时自动打开命名空间或模块,则可以将 AutoOpen 属性应用于程序集。 还可以将 AutoOpen 属性应用于模块,以在打开父模块或命名空间时自动打开该模块。 有关详细信息,请参阅 AutoOpenAttribute

RequireQualifiedAccess 属性

某些模块、记录或联合类型可以指定 RequireQualifiedAccess 属性。 引用这些模块、记录或联合的元素时,无论是否包括导入声明,都必须使用限定的名称。 如果在定义常用名称的类型上以策略方式使用此属性,则有助于避免名称冲突,从而使代码对库中的更改更具弹性。 有关详细信息,请参阅 RequireQualifiedAccessAttribute

另请参阅