I am processing simple strings of the format "1s:1d", "100:5000", etc with this regex:
let retention_matcher = regex::Regex::new({r"^(\d+)([smhdy])?:(\d+)([smhdy])?$"}).unwrap();
I know this regex should only match once so I want to run the regex for captures and check the number of captures.
let iter = retention_matcher.captures_iter(ts);
let count = iter.count();
println!("iter.count(): {}", count);
let _ : Vec<Option<(u64,u64)>> = iter.map(|regex_match| {
let retval = retention_spec_to_pair(regex_match);
println!("precision_opt: {:?}", retval);
retval
}).collect();
The issue is that the count()
method moves iter
and I can no longer use it.
src/bin/whisper.rs:147:42: 147:46 error: use of moved value: `iter`
src/bin/whisper.rs:147 let _ : Vec<Option<(u64,u64)>> = iter.map(|regex_match| {
^~~~
src/bin/whisper.rs:144:21: 144:25 note: `iter` moved here because it has type `regex::re::FindCaptures<'_, '_>`, which is non-copyable
src/bin/whisper.rs:144 let count = iter.count();
This does not make sense to me. Should the count
method just return a copyable usize
value and not move iter
? How can I work around this issue?
I suspect that you're thinking of iter
as being an abstract sequence of captures. It is more accurate to think of it as representing a position within an abstract sequence of captures. The basic thing any iterator knows to do is advance to the next item in a sequence; that is, you can advance the position and get the next element in the sequence.
count
moves iter
because in order to count how many elements are in the sequence, it has to generate the whole sequence. This necessarily modifies the iterator by stepping it through the whole sequence. It moves because after calling count
, the iterator really isn't useful any more. By definition, it must be past the end of the sequence!
Sadly, it doesn't look like the iterator type in question (FindCaptures
) is Clone
, so you can't just make a copy of it.
The solution would be to restructure your code to not call count
. If you want to get the first element and ensure there are no more, the simplest pattern would be:
let mut iter = ...;
if let Some(regex_match) = iter.next() {
// Ensure that there is no next element.
assert_eq!(iter.next(), None);
// process regex_match ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With