Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I combine implementations of a trait for Vec<T> as well as Vec<&T>

I have a trait that I own:

trait Reducer {
  fn reduce(&self) -> Res;
}

I want to implement for the following cases:

struct MyStruct {... fields ...}

impl Reducer for Vec<MyStruct> {
  fn reduce(&self) -> Res { ... some implementation ... }
}

I want to get for as cheap as possible (not duplicating code etc.) for the refs of objects in Vec:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

for instance:

// I want this please:

impl Reducer for Vec<&MyStruct> {
  // it's the same implementation as before
}

How should I change my impl signature to satisfy both cases?

>Solution :

Using the Borrow trait you can generalize for all types that can be borrowed as a &MyStruct (which in particular includes MyStruct and &MyStruct):

use std::borrow::Borrow;

trait Reducer {
  fn reduce(&self) -> Res;
}

struct MyStruct;
struct Res;

impl<T: Borrow<MyStruct>> Reducer for Vec<T> {
    fn reduce(&self) -> Res {
        for t in self {
            let _t: &MyStruct = t.borrow();
            // do something with `_t`
        }
        Res
    }
}

fn main() {
    let v: Vec<MyStruct> = vec![];
    let v_ref: Vec<&MyStruct> = vec![];

    // fully qualified because it gets mangled with `Iterator::reduce` otherwise.
    Reducer::reduce(&v);
    Reducer::reduce(&v_ref);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading