let Bindings

绑定将标识符与值或函数相关联。 使用 let 关键字将名称绑定到值或函数。

语法

// Binding a value:
let identifier-or-pattern [: type] =expressionbody-expression
// Binding a function value:
let identifier parameter-list [: return-type ] =expressionbody-expression

注解

let 绑定表达式中使用关键字来定义一个或多个名称的值或函数值。 表达式的最 let 简单形式将名称绑定到简单值,如下所示。

let i = 1

如果使用新行将表达式与标识符分开,则必须缩进表达式的每一行,如以下代码所示。

let someVeryLongIdentifier =
    // Note indentation below.
    3 * 4 + 5 * 6

可以指定包含名称的模式,例如元组,如以下代码所示,而不是只指定一个名称。

let i, j, k = (1, 2, 3)

正文表达式是在其中使用名称的表达式。 正文表达式显示在其自身的行上,缩进以与关键字中的 let 第一个字符完全对齐:

let result =

    let i, j, k = (1, 2, 3)

    // Body expression:
    i + 2 * j + 3 * k

let绑定可以在模块级别、类类型的定义或本地范围(如函数定义)中显示。 let模块或类类型顶层的绑定不需要具有正文表达式,但在其他范围级别,需要正文表达式。 绑定名称在定义点之后可用,但在绑定出现前 let 的任何点都不可用,如以下代码所示。

// Error:
printfn "%d" x
let x = 100
// OK:
printfn "%d" x

函数绑定

函数绑定遵循值绑定的规则,但函数绑定包括函数名称和参数,如以下代码所示。

let function1 a = a + 1

通常,参数是模式,例如元组模式:

let function2 (a, b) = a + b

let绑定表达式的计算结果为最后一个表达式的值。 因此,在下面的代码示例中,计算其值为 result100 * function3 (1, 2)300

let result =
    let function3 (a, b) = a + b
    100 * function3 (1, 2)

有关详细信息,请参阅函数

类型批注

可以通过包括冒号(:)后跟类型名称)来指定参数的类型,这些类型都括在括号中。 还可以通过在最后一个参数后面追加冒号和类型来指定返回值的类型。 其整数作为参数类型的完整类型批注 function1如下所示。

let function1 (a: int) : int = a + 1

如果没有显式类型参数,则类型推理用于确定函数的参数类型。 这可以包括自动通用化要通用的参数的类型。

有关详细信息,请参阅 自动通用化类型推理

让类中的绑定

let绑定可以出现在类类型中,但不出现在结构或记录类型中。 若要在类类型中使用 let 绑定,该类必须具有主构造函数。 构造函数参数必须出现在类定义中的类型名称之后。 let类类型中的绑定定义该类类型的私有字段和成员,以及do类型中的绑定构成类型的主要构造函数的代码。 下面的代码示例演示一个 MyClass 具有私有字段 field1field2.

type MyClass(a) =
    let field1 = a
    let field2 = "text"
    do printfn "%d %s" field1 field2
    member this.F input =
        printfn "Field1 %d Field2 %s Input %A" field1 field2 input

其范围field1field2限制为声明它们的类型。 有关详细信息,请参阅 let中的绑定。

允许绑定中的类型参数

let模块级别、类型或计算表达式中的绑定可以具有显式类型参数。 表达式中的 let 绑定(如函数定义中)不能具有类型参数。 有关详细信息,请参阅 泛型

允许绑定的属性

属性可以应用于模块中的顶级 let 绑定,如以下代码所示。

[<Obsolete>]
let function1 x y = x + y

Let Bindings 的范围和辅助功能

绑定出现后,使用 let 绑定声明的实体的范围仅限于包含范围(如函数、模块、文件或类)的部分。 因此,可以说,允许绑定将名称引入范围。 在模块中,只要模块可访问,模块的客户端就可以访问允许绑定值或函数,因为模块中的允许绑定编译为模块的公共函数。 相比之下,类中的绑定对类是私有的。

通常,模块中的函数必须在客户端代码使用时按模块的名称进行限定。 例如,如果模块 Module1 具有函数 function1,则用户将指定 Module1.function1 引用该函数。

模块的用户可以使用导入声明使该模块中的函数可供使用,而无需由模块名称限定。 在刚才提到的示例中,模块的用户可以使用导入声明 open Module1 打开模块,然后直接引用 function1 该模块。

module Module1 =
    let function1 x = x + 1.0

module Module2 =
    let function2 x =
        Module1.function1 x

open Module1

let function3 x =
    function1 x

某些模块具有 RequireQualifiedAccess 属性,这意味着必须用模块的名称限定它们公开的函数。 例如,F# 列表模块具有此属性。

有关模块和访问控制的详细信息,请参阅 模块访问控制

另请参阅