let 绑定 (F#)
绑定可将一个标识符与一个值或函数关联在一起。 使用 let 关键字可将一个名称绑定到一个值或函数。
// Binding a value:
let identifier-or-pattern [: type] =
expression
body-expression
// Binding a function value:
let identifier parameter-list [: return-type ] =
expression
body-expression
备注
可在绑定表达式中使用 let 关键字为一个或多个名称定义值或函数值。 let 表达式的最简单形式是将一个名称绑定到一个简单值,如下所示。
let i = 1
如果使用新行将表达式与标识符分离,则必须将表达式的每个行缩进,如以下代码中所示。
let someVeryLongIdentifier =
// Note indentation below.
3 * 4 + 5 * 6
还可以指定包含多个名称的模式(如元组),而不仅仅是指定一个名称,如以下代码中所示。
let i, j, k = (1, 2, 3)
body-expression 是在其中使用名称的表达式。 主体表达式出现在自己的行上,并缩进到与 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 绑定表达式的计算结果为最后一个表达式的值。 因此,在下面的代码示例中,将从 100 * function3 (1, 2) 计算 result 的值,计算结果为 300。
let result =
let function3 (a, b) = a + b
100 * function3 (1, 2)
有关更多信息,请参见函数 (F#)。
类型批注
可以通过以下方式为参数指定类型:包含一个冒号 (:),其后跟一个类型名称,并用括号将它们括起来。 也可以通过在最后一个参数后追加冒号和类型来指定返回值的类型。 function1 的完整类型批注(其中整数作为参数类型)如下所示。
let function1 (a: int) : int = a + 1
没有显式类型参数时,会使用类型推理来确定函数的参数类型。 这可能包括自动将参数的类型通用化为泛型。
有关更多信息,请参见自动泛化 (F#)和类型推理 (F#)。
类中的 let 绑定
let 绑定可以出现在类类型中,但不可以出现在结构或记录类型中。 若要在一个类类型中使用 let 绑定,相应的类必须具有主构造函数。 构造函数参数必须出现在类定义中的类型名称之后。 一个类类型中的 let 绑定为该类类型定义私有字段和成员,并与该类型中的 do 绑定一起,构成该类型的主构造函数的代码。 下面的代码示例演示了包含私有字段 field1 和 field2 的类 MyClass。
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
field1 和 field2 的范围限制在声明它们的类型中。 有关更多信息,请参见类中的 let 绑定 (F#)和 类 (F#)。
let 绑定中的类型参数
在类型或计算表达式中,模块级别的 let 绑定可以具有显式类型参数。 表达式(如函数定义)中的 let 绑定不能具有类型参数。 有关更多信息,请参见泛型 (F#)。
let 绑定上的特性
可以对模块中的顶级 let 绑定应用特性,如下面的代码所示。
[<Obsolete>]
let function1 x y = x + y
范围和辅助功能的 let 绑定
实体的大小声明的 let 绑定绑定到包含范围中 (如函数、模块、文件或类),在绑定出现后。 因此,可以添加 let 绑定引入名称范围内。 在模块中,一个允许一个值或函数对于模块的客户端来访问,只要模块来访问,因此,因为使模块中的绑定编译到模块的公共函数。 相反,使类中的绑定是私有的。类。
通常,必须限定模块中的函数名为的模块,当使用由客户端代码。 例如,因此,如果模块 Module1 具有函数 function1,用户将指定 Module1.function1 引用该功能。
模块的用户可以使用导入声明使该模块内的功能可用于使用,而不需要限定按模块名称。 中提到的示例中,模块的用户在这种情况下可以打开模块使用导入声明打开 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# 列表模块具有此特性。
有关模块和访问控件的更多信息,请参见 模块 (F#) 和 访问控制 (F#)。