I have this code here, where I try to extract some text based on a delimiter:
//not working
let mut text: Option<String> = None;
for d in DELIMITERS {
let split_res = full_text.split_once(d);
if let Some((_, t0)) = split_res {
let t = t0.to_string();
match text {
None => text = Some(t),
Some(t2) => if t.len() < t2.len() {
text = Some(t);
}
}
}
}
But I get these errors from the compiler
^^ value moved here, in previous iteration of loop
note: these 2 reinitializations might get skipped
What's going on here?
Why can't I pattern match on text? Is the problem that my text
variable gets consumed? I can't really understand where and how?
Changing the code to use as_ref()
on text
fixes the error but I don't understand why this is necessary:
//working
let mut text: Option<String> = None;
for d in DELIMITERS {
let split_res = full_text.split_once(d);
if let Some((_, t0)) = split_res {
let t = t0.to_string();
match text.as_ref() {
None => text = Some(t),
Some(t2) => if t.len() < t2.len() {
text = Some(t);
}
}
}
}
CodePudding user response:
If you do not use as_ref
, you are moving the object hence consuming it, so it is not available in the next iteration.
You can also match a reference:
match &text {}
Or you can take
the inner value, leaving a None
behind, that way you do not drop it. And since you re-assignate it afterwards keeps the same functionality:
const DELIMITERS: [&'static str; 2] = [
"example",
"not-found",
];
fn main() {
let full_text = String::from("This is an example test");
let mut text: Option<String> = None;
for d in DELIMITERS {
let split_res = full_text.split_once(d);
if let Some((_, t0)) = split_res {
let t = t0.to_string();
match text.take() {
None => text = Some(t),
Some(t2) => if t.len() < t2.len() {
text = Some(t);
}
}
}
}
if let Some(t) = text {
println!("{}", t);
}
}