Reputation: 302
I'm quite new to Rust and still having issues with the concept of lifetime specifiers.
I have a Vec
(or any other collection) of references. Now I want to replace a specific reference with another reference to a newly created local variable. The problem now is, that the local new variable has a shorter lifetime than the vector which would invalidate the reference.
An example code that tries do do what I want but throws an compile time error:
fn main() {
let values = ["one".to_string(), "lorem".to_string(), "three".to_string()];
let borrowed_values = vec![&values[0], &values[1], &values[2]];
println!("{:?}", do_the_impossible(borrowed_values));
}
fn do_the_impossible(mut data: Vec<&String>) -> Vec<&String> {
let replacement = "two".to_string();
data[1] = &replacement;
return data;
}
The question now is: How do I create a new variable with the same lifetime as the vector?
I want to use references because cloning the objects would be pretty expensive.
My initial idea was to use lifetime specifiers which indicate that the local variable should live as long as the vector does. But I couldn't find a syntactical right way to do this. Is it even possible to specify the lifetime of a local variable?
And if not, is there any other way to avoid cloning the elements of the vector? My last resort would be using an Rc
pointer.
Thanks in advance!
Upvotes: 5
Views: 1699
Reputation: 2596
This sounds like a use case for std::borrow::Cow
, which allows you to have a value which may be backed by a borrow or an owned value.
You would instead write something like:
use std::borrow::Cow;
fn main() {
let values = ["one".to_string(), "lorem".to_string(), "three".to_string()];
let borrowed_values: Vec<_> = values.iter().map(Cow::Borrowed).collect();
println!("{:?}", do_the_impossible(borrowed_values));
}
fn do_the_impossible<'a>(mut data: Vec<Cow<'a, String>>) -> Vec<Cow<'a, String>> {
let replacement = "two".to_string();
data[1] = Cow::Owned(replacement);
return data;
}
Upvotes: 5