Is it possible to implement a function of fn foo (v: Vec<(String, String)>) -> Vec<(&String, &String)>
?
I tried it as v.into_iter().map(|(a, b)| (&a, &b)).collect()
.
I don't think that exact function signature would be possible, because you're not allowed to return references to data owned by the current function, which it would be because the vec was passed by value. But you could do it if you can pass the vec by reference to the conversion function instead (playground):
fn vec_to_vec_ref (strings: &Vec<(String, String)>) -> Vec<(&String, &String)> {
let mut vec_ref = Vec::new();
for (a, b) in strings {
vec_ref.push((a, b));
}
vec_ref
}
fn vec_ref (strings: Vec<(&String, &String)>) {
println!("Success! {:?}", strings);
}
fn main() {
let strings = vec![(String::from("Foo"), String::from("Bar"))];
vec_ref(vec_to_vec_ref(&strings));
}
You almost got it, simply replace into_iter
for iter
:
let strings = vec![(String::from("Foo"), String::from("Bar"))]
let strings_refs: Vec<(&String, &String)> = strings.iter().map(|(a, b)| (a, b)).collect();
With into_iter
you are taking the values owned ((String, String)
) meanwhile with iter
you get a reference to the tuple (&(String, String)
), by repacking the inner String references in the map
section we get the final target result (&String, &String)
.
We can expand that to functions, for example, taking an iterator already, or an slice over the data:
fn foo<'a> (v: impl Iterator<Item=&'a(String, String)>) -> Vec<(&'a String, &'a String)> {
v.map(|(a, b)| (a, b)).collect()
}
fn foo_slice<'a> (v: &'a [(String, String)]) -> Vec<(&'a String, &'a String)> {
v.iter().map(|(a, b)| (a, b)).collect()
}