I would like to be able to pass mutable objects by reference to a function to have it 'work on them' but am struggling. I tried all most feasible combinations of lifetimes in the function definition and this seemed to be the only one to compile (but missed the correct one pointed out below). I suspect I need to use a Rust 'wrapper' but can't find any examples of what I would think was a very standard thing to do.
fn add<'a>(vec: &'a mut Vec<&'a str>, txt: &'a str) {
vec.push(txt);
for t in vec.iter() {
print!("{} ", t);
}
}
fn main() {
let mut st = vec!["hello"];
let words = vec!["world", "again", "!"];
//for txt in words.iter() { // what I wanted to do
// add(&mut st, txt);
//}
st.push(","); // experiment works
st.push("cruel");
{
add(&mut st, words[0]); // but this borrows to the end of main(){}
} // instead of here
// add(&mut st, words[1]); // so, for instance, this is a second borrow and not allowed
}
EDIT - answered as below in comments.
Thank you so much @Shepmaster and @trentcl, I had been singing the praises of the explicit and helpful rust debugger messages but failed to read
error[E0623]: lifetime mismatch
--> src/main.rs:3:12
|
2 | fn add(vec: &mut Vec<&str>, txt: &str) {
| ---- ---- these two types are declared with different lifetimes...
3 | vec.push(txt);
| ^^^ ...but data from `txt` flows into `vec` here
When I first added the lifetime specs. I put them in initially for the two main arguments and only added the <&str> when I got a further error. As you say it should be done like this:
fn add<'a>(vec: &mut Vec<&'a str>, txt: &'a str) {
vec.push(txt);
}
fn main() {
let mut st = vec!["hello"];
let words = vec!["world", "again", "!"];
for txt in words.iter() { // what I wanted to do
add(&mut st, txt);
}
for txt in st.iter() {
print!("{} ", txt);
}
}