My function returns a Vec
of references to a tuple, but I need a Vec
of tuples:
use std::collections::HashSet;
fn main() {
let maxs: HashSet<(usize, usize)> = HashSet::new();
let mins: HashSet<(usize, usize)> = HashSet::new();
let intersection = maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>();
}
How should I do the conversion?
Error:
19 | maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference
|
= note: expected type `std::vec::Vec<(usize, usize)>`
found type `std::vec::Vec<&(usize, usize)>`
I'm using a for
loop to do the conversion, but I don't like it and I think there should be a mode idiomatic way:
for t in maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>().iter() {
output.push(**t);
}
Rust 1.36.0 introduced copied
which works like cloned
, but uses the Copy
trait, which has the requirement, that the copy is cheap (e.g. a memcpy
only). If you have primitive types or types that implement Copy
you can use that instead.
To make your example work, use cloned
and then collect
.
let maxs: HashSet<(usize,usize)> = HashSet::new();
let mins: HashSet<(usize,usize)> = HashSet::new();
let output: Vec<(usize, usize)> = maxs.intersection(&mins).cloned().collect();
This solution will work with any type than implements Clone
:
pub fn clone_vec<T: Clone>(vec: Vec<&T>) -> Vec<T> {
vec.into_iter().cloned().collect()
}
If your function accepts a slice, you have to use cloned
twice.
pub fn clone_slice<T: Clone>(slice: &[&T]) -> Vec<T> {
slice.iter().cloned().cloned().collect()
}
The reason for this is that iter()
returns an iterator over references of the slice, which results in &&T
.
If you happen to have a type that does not implement Clone
, you can mimic the behavior with map
pub struct Foo(u32);
impl Foo {
fn dup(&self) -> Self {
Foo(self.0)
}
}
pub fn clone_vec(vec: Vec<&Foo>) -> Vec<Foo> {
vec.into_iter().map(|f| f.dup()).collect()
}
pub fn clone_vec2(vec: Vec<&Foo>) -> Vec<Foo> {
// this function is identical to `clone_vec`, but with another syntax
vec.into_iter().map(Foo::dup).collect()
}
(playground)
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