How to choose to use between `Vec` and `Slice`?

I have two structs, their function are same. The only defference between them is that A owes a Vec but B owes a slice:

struct A {
    v: Vec<i32>
}
struct B<'a> {
    v: &'a [i32]
}

impl A {
    fn get_value(&self) -> &[i32] {
        &self.v[..]
    }
}

impl<'a> B<'a> {
    fn get_value(&self) -> &[i32] {
        &self.v[..]
    }
}

let a_vec: Vec<i32> = vec![1,2,3];
let a = A { v: a_vec };
println!("{:?}", a.get_value());
{
    let b = B { v: &a.v[..] };
    println!("{:?}", b.get_value());
}

As can been seen, the method get_value from A and B are the same, so I think the code maybe verbose.
Is there a way I can define a struct C, which can have the instance like both A and B?

struct C {
    v: AbstractVec<i32>
}

impl C {
    fn get_value(&self) -> &[i32] {
        &self.v[..]
    }
}

let a_vec: Vec<i32> = vec![1,2,3];
let a = C { v: a_vec }; // like struct A
println!("{:?}", a.get_value());
{
    let b = C { v: &a.v[..] }; // like struct B
    println!("{:?}", b.get_value())
}

You could do something like this:

struct D<X> {
    buffer: X
}

impl<X:Borrow<[i32]>> D<X> {
    // These methods work for both Vec<i32> and &[i32]
    fn get_value(&self)->&[i32] {
        self.buffer.borrow()
    }
}

impl D<Vec<i32>> {
   // Vec-specific methods go here
}
5 Likes

And, as a bonus, that lets them work for D<[i32; 13]> too!

https://doc.rust-lang.org/std/primitive.array.html#impl-Borrow<[T]>-for-[T%3B%20N]

4 Likes