如何在Rust的不同闭包中重复借用闭包外的变量?

mkshixfv  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(176)

这是核心代码,它返回Vec<(&'a str, i32)>的类型当我运行这段代码时,

let mut i = 0;
contents.lines().filter(|x| {
    i += 1;
    x.to_lowercase().contains(&query.to_lowercase())
}).map(|x|
    (x, i)
).collect()

它会警告:

contents.lines().filter(|x| {
   |                             --- mutable borrow occurs here
56 |         i += 1;
   |         - first borrow occurs due to use of `i` in closure
57 |         x.to_lowercase().contains(&query.to_lowercase())
58 |     }).map(|x|
   |        --- ^^^ immutable borrow occurs here
   |        |
   |        mutable borrow later used by call
59 |         (x, i)
   |             - second borrow occurs due to use of `i` in closure

那么我该如何更正这段代码呢?

xzlaal3s

xzlaal3s1#

修复这段代码的最佳方法是意识到你所做的实际上是enumerate(),索引从1开始而不是从0开始,所以:

contents.lines().enumerate().filter(|(_, x)| {
    x.to_lowercase().contains(&query.to_lowercase())
}).map(|(i, x)|
    (x, i + 1)
).collect()

或者:

contents.lines().zip(1..).filter(|(x, _)| {
    x.to_lowercase().contains(&query.to_lowercase())
}).collect()
nwlqm0z1

nwlqm0z12#

@Chayim Friedman谢谢你的提示!现在我可以使用filter_map方法来达到我自己的目的,并且已经学会了熟练使用zip的方法。

let mut i = 0;
    contents.lines().filter_map(|x| {
        i += 1;
        if x.to_lowercase().contains(&query.to_lowercase()) {
            Some((x, i))
        } else {
            None
        }
    }).collect()

相关问题