Reputation: 101
This is the core codes, which return the type of Vec<(&'a str, i32)>
When I run this code,
let mut i = 0;
contents.lines().filter(|x| {
i += 1;
x.to_lowercase().contains(&query.to_lowercase())
}).map(|x|
(x, i)
).collect()
it alerts that:
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
So how can I correct this code?
Upvotes: 0
Views: 100
Reputation: 101
@Chayim Friedman
Thanks for your tips!
Now I could use the filter_map
method to achieve my own aim and has learnt a skilled way to use the 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()
Upvotes: 1
Reputation: 70860
The best way to fix this code is to realize that what you're doing is essentially enumerate()
with index starting from 1 instead of zero, so either:
contents.lines().enumerate().filter(|(_, x)| {
x.to_lowercase().contains(&query.to_lowercase())
}).map(|(i, x)|
(x, i + 1)
).collect()
Or:
contents.lines().zip(1..).filter(|(x, _)| {
x.to_lowercase().contains(&query.to_lowercase())
}).collect()
Upvotes: 1