48-函数中的闭包
3 分钟阅读
译文 · 基于 Easy Rust
函数中的闭包
闭包是伟大的。那么我们如何把它们放到自己的函数中呢?
你可以创建自己的函数来接受闭包,但是在函数里面就不那么自由了,你必须决定类型。在函数外部,一个闭包可以在Fn、FnMut和FnOnce之间自行决定,但在函数内部你必须选择一个。最好的理解方式是看几个函数签名。
这里是.all()的那个。我们记得,它检查一个迭代器,看看所有的东西是否是true(取决于你决定是true还是false)。它的部分签名是这样说的。
| |
fn all<F>:这告诉你有一个通用类型F。一个闭包总是泛型,因为每次都是不同的类型。
(&mut self, f: F):&mut self告诉你这是一个方法。f: F通常你看到的是一个闭包:这是变量名和类型。 当然,f和F并没有什么特别之处,它们可以是不同的名字。如果你愿意,你可以写my_closure: Closure–这并不重要。但在签名中,你几乎总是看到f: F。
接下来是关于闭包的部分:F: FnMut(Self::Item) -> bool。在这里,它决定了闭包是 FnMut,所以它可以改变值。它改变了Self::Item的值,这是它所取的迭代器。而且它必须返回 true 或 false。
这里是一个更简单的签名,有一个闭包。
| |
这只是说它接受一个闭包,取值(FnOnce=取值),而不返回任何东西。所以现在我们可以调用这个什么都不取的闭包,做我们喜欢做的事情。我们将创建一个 Vec,然后对它进行迭代,只是为了展示我们现在可以做什么。
| |
一个更真实的例子,我们将再次创建一个 City 结构体。这次 City 结构体有更多关于年份和人口的数据。它有一个 Vec<u32> 来表示所有的年份,还有一个 Vec<u32> 来表示所有的人口。
City有两个方法:new()用于创建一个新的City, .city_data()有个闭包参数。当我们使用 .city_data() 时,它给我们提供了年份和人口以及一个闭包,所以我们可以对数据做我们想做的事情。闭包类型是 FnMut,所以我们可以改变数据。它看起来像这样:
| |
这将打印出我们调用.city_data().的所有时间的结果:
| |