I am new to Rust and have run into a problem similar to the following a few times:
fn main() {
let mut as_str: Vec<&String> = Vec::new();
for i in [1, 2, 3, 4, 5].iter() {
let i_str = i.to_string();
as_str.push(&i_str);
}
}
Which yields the following error:
<anon>:6:22: 6:27 error: `i_str` does not live long enough
<anon>:6 as_str.push(&i_str);
^~~~~
How do I transfer ownership of the string to the vector (do not want to copy)? Do I need a lifetime? Should it be a str or a String (supposing I do not want to mutate the items themselves in the vector)?
When doing assignments ( let x = y ) or passing function arguments by value ( foo(x) ), the ownership of the resources is transferred. In Rust-speak, this is known as a move. After moving resources, the previous owner can no longer be used.
Rust verifies the ownership rules using the borrow checker. The borrow checker verifies the ownership model and decides if a value in memory (stack or heap) is out of scope or not. If a value is out of its scope, it's not accessible to other parts of the program unless it's borrowed.
Give the vector a String
, not a reference to one. A Foo
is owned, a &Foo
is borrowed.
fn main() {
let mut as_str: Vec<String> = Vec::new();
for i in [1, 2, 3, 4, 5].iter() {
let i_str = i.to_string();
as_str.push(i_str);
}
}
In your example, you are allocating a String
inside the for loop body, then taking a reference to it. Since nothing owns the String
, it is dropped at the end of the loop body. That means that any references would become invalid. Rust prevents this memory safety violation.
In the real world, you'd never need to specify the type here, type inference is enough:
fn main() {
let mut as_str = Vec::new();
for i in [1, 2, 3, 4, 5].iter() {
let i_str = i.to_string();
as_str.push(i_str);
}
}
And you'd probably use map
to convert one slice of things to another:
fn main() {
let as_str: Vec<_> = [1, 2, 3, 4, 5].iter().map(|i| i.to_string()).collect();
}
Incidentally, it never makes sense to have a &String
; you might as well have a &str
.
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