closures.mdcommit 6ba952020fbc91bad64be1ea0650bfba52e6aab4有时为了整洁和复用打包一个函数和自由变量(free variables)是很有用的。自由变量是指被用在函数中来自函数内部作用域并只用于函数内部的变量。对此,我们用一个新名字“闭包”而且 Rust 提供了大量关于他们的实现,正如我们将看到的。语法闭包看起来像这样:let plus_one = |x: i32| x + 1;
闭包向来给包括 JavaScript 程序员在内的程序员以神秘,高深的感觉,事实上,闭包的概念在函数式编程语言中算不上是难以理解的知识。如果对作用域,函数为独立的对象这样的基本概念理解较好的话,理解闭包的概念并在实际的编程实践中应用则颇有水到渠成之感。
闭包是什么?先来看看维基百科上的描述:在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是 引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
Rust 不仅命名函数,还命名匿名函数。匿名函数有一个关联的环境被称为“闭包”,因为他们关闭了一个环境。如我们将会看到的,Rust 对它们有完美的实现。 语法闭包看起来是这样的:let plus_one = |x: i32| x + 1;assert_eq!(2, plus_one(1));我们创建一个绑定,plus_one 并将其分配给一个闭包。关闭管道之间的参数(|),并且主体是一个表达式,在本例中是 x + 1。
介绍本章我们将介绍在 JavaScript 里大家经常来讨论的话题 —— 闭包(closure)。闭包其实大家都已经谈烂了。尽管如此,这里还是要试着从理论角度来讨论下闭包,看看 ECMAScript 中的闭包内部究竟是如何工作的。正如在前面的文章中提到的,这些文章都是系列文章,相互之间都是有关联的。
闭包作为参数(Taking closures as arguments)现在我们知道了闭包是 trait,我们已经知道了如何接受和返回闭包;就像任何其它的 trait!这也意味着我们也可以选择静态或动态分发。首先,让我们写一个获取可调用结构的函数,调用它,然后返回结果:fn call_with_one<F>(some_closure: F) -> i32 where F : Fn(i32) ->
Rust 的闭包实现与其它语言有些许不同。它们实际上是trait的语法糖。在这以前你会希望阅读trait章节,和trait对象。都理解吗?很好。理解闭包底层是如何工作的关键有点奇怪:使用()调用函数,像foo(),是一个可重载的运算符。到此,其它的一切都会明了。在Rust中,我们使用trait系统来重载运算符。调用函数也不例外。
基本形式闭包看起来像这样:let plus_one = |x: i32| x + 1;assert_eq!(2, plus_one(1));我们创建了一个绑定,plus_one,并把它赋予一个闭包。闭包的参数位于管道(|)之中,而闭包体是一个表达式,在这个例子中,x + 1。记住{}是一个表达式,所以我们也可以拥有包含多行的闭包:let plus_two = |x| { let mut result: i32 = x; result += 1; result += 1;
关注时代Java