在本文中,我们将研究F#中的绑定,尤其是我们将研究Let / Use / Do。 现在您可能会问自己是什么绑定,并且由于我们尚未检查它们,所以现在该讨论一下了。
简而言之,绑定将标识符与值或函数相关联。
让
您可以使用let关键字将名称与值或函数相关联。 实际上,Let有一个细微的不同用法,其中一个在模块的顶层声明,然后另一个在我们定义一些局部上下文的地方声明。 这是他们两个的例子:
module DemoModule = let someFunction = let a = 1 let b = 2 a * b
我们可以使用完全限定的名称来访问someFunction,例如DemoModule.someFunction,但是嵌套的Let(a,b)绑定仅可用于Let顶级。 通常,当我们使用Let绑定声明内部模块的某些值时,会看到更多的情况,因此让我们集中精力在这里(尽管很重要的一点是,知道可以在模块级别使用Let)。
因此,让我们来看更多示例。
let aString ="this is a string" let aInt = 12 let aDecimal = 12.444 let aPiFunction () = Math.PI let aSquareRootFunction (x) = Math.Sqrt(x) let aFullyTypedSquareRootFunction (x :float) = Math.Sqrt(x) let a,b = "a","tuple"
您可以看到我们可以使用Let绑定来绑定多个值,这些值可以是各种类型,例如:
- 整数
- 小数
- 没有输入参数的功能
- 具有输入参数的函数(其中类型为F#的逻辑推理系统将正确选择类型)
- 具有完全定义的参数类型的函数
- 元组(在这种情况下,字符串*字符串元组)
在其他地方,您可以在类中看到Let绑定,但是我们将在本系列的下一篇文章中对此进行更详细的讨论。
您可以阅读有关MSDN上的Let绑定的更多信息。使用方法
Use绑定与Let绑定非常相似,因为它会将值绑定到表达式的结果。 主要区别在于,使用绑定旨在与IDisposable类型一起使用,并在其值不在范围内时自动删除该值。 这与.NET using关键字非常相似,尽管我不认为F#Use绑定与.NET中的使用完全相同,因为.NET中的using关键字实际上是try /最后调用Dispose( )。
在上一篇有关文本格式设置的文章中,我们已经看到了Use绑定的示例,但是为了提醒自己,让我们再来看一看。
use sw = new StreamWriter(@"c:\temp\fprintfFile.txt") fprintf sw "This is a string line %s\r\n" "cat" fprintf sw "This is a int line %i" 10 sw.Close()
在此示例中,Use绑定保证了StreamWriter方法将在调用sw.Close()之后调用其Dispose()方法,如上所示。
Use仅适用于IDisposables,如果尝试将其用于其他用途,则会出现编译错误,如下所示:

由于Dispose()方法是在Use绑定的末尾调用的,因此应注意不要返回与Let关联的值。
let Write = use sw = new StreamWriter(@"c:\temp\fprintfFile.txt") sw
如果您绝对需要传回IDisposable,这是Use绑定的一部分,则可以改用回调。 这样的事情会起作用,但是我会停下来问自己,如果您做这些事情,您是否正确地设计了您的设计:
let Write callback = use sw = new StreamWriter(@"c:\temp\fprintfFile.txt") fprintf sw "Write is writing to the StreamWriter" callback sw sw let callback sw = fprintf sw "sw is the StreamWriter" let disp = Write callback
做
do绑定用于执行代码,而无需定义函数或值。 绑定必须始终返回Unit(无值/无效)。 在许多情况下,您可以省略Do绑定,一切都会按预期进行。
这是一些使用Do绑定的示例。
do printf "doing the do" //oh oh not a unit do printf "print a sum %i" 1 + 1 do 1 + 1
如果我改用上面的代码给您看一个屏幕截图,您会发现如果尝试对非Unit结果使用Do,则编译器会抱怨。

您有两种选择:
我在下面展示了每个示例:
let x = 1 + 1 do printf "print a sum %i" x do (1+1 |> ignore)
放开 使用! 做吧!
尽管我不想讨论它们,但有时您可能会偶然看到Let! 使用! 执行!,当您执行此操作时,这就是所谓的计算表达式的一部分。 您很可能会在F#异步工作流中看到这一点,我们将在最后一篇文章中介绍。 如果我足够理解,我什至可以尝试解释如何创建自己的“计算表达式”,尽管它们是一个相当抽象的概念和一个相当复杂的主题,所以现在不是时候了。