Function taking a reference of vector as parameter

I have a function taking a reference of vector as parameter

fn f1(v: &Vec<SomeStruct>) {
    ...
}

Later, some code return Vec<&SomeStruct> to feed into f1. I'd like to avoid copying SomeStruct (since it's heavy to do so), so it sounds like I need another function

fn f2(v: &Vec<&SomeStruct>) {
    ...
}

I don't want to duplicate the exact logic in both f1 and f2. What is the best way solve the problem in Rust?

Nothing special to me, just build a new vector:

fn f1(v: &Vec<SomeStruct>) {
    let mut ref_v: Vec<&SomeStruct> = Vec::new();
    v.iter().for_each(|item| ref_v.push(item));
    f2(&ref_v);
}

It looks like you want generics for abstracting over borrowed and owned values:

fn f<T>(v: &[T]) where T: AsRef<SomeStruct> {
    ...
}

By the way, don't take vectors by reference, accept a slice instead. Taking a vector by immutable reference has no added value, since you can't grow it, but not taking a slice prevents downstream code from using your function with anything but a vector. If you take a slice, others can call your function with other, non-Vec containers that also deref to a slice.

8 Likes

Perrhaps you can also replace them with a generic function using impl Iterator and Borrow :

fn<‘a, T: std::borrow::Borrow<&’a SomeStruct>>(iter: impl Iterator<Item=T>) { … }

This is awesome! It's exactly what I'm looking for.

I came across AsRef before but didn't know it is the Trait for this usage. In general, how does a Rust newbie quickly learn or find the Trait which suits his/her use case?

You read a lot of real life code written by others, and you will see the most frequently used traits and methods. You an also just browse the reference of the stdlib freely, you might come across interesting things.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.