0

Given this struct:

pub struct A {
    pub C: B,
}

I'm looking create Rust container with elements of A, and access A.C in that generic Rust container. Here is such a container:

pub struct MyArray<A, C> {
    data: Vec<A>,
    size: usize,
}

impl<A, C> MyArray {
    // Access the value in the ith element of data
    pub fn get_value(self, i: u64) -> u64 {
        self.data[i].C
    }
}

Given the following struct:

pub struct House {
    pub num_rooms: u64, 
} 

I want to instantiate a generic types like this:

let h: MyArray<House, num_rooms> = MyArray(6);

let d: MyArray<Cat, num_lives> = MyArray(10);

Then I want do be able to call h.func(5) to get the value of specified field in the 6th element of the Rust container.

I'm not sure if this is possible at all. If it is, macros / generics are probably needed.

NutellaFan
  • 85
  • 8
  • What you want if I guess right, is a trait, but your question is very unclear, there is no link between `struct A` and `struct MyArray` curently. Also A is not a suitable name for a struct. – Stargateur Nov 01 '18 at 02:00
  • I believe your question is answered by the answers of [Is it possible to access struct fields from within a trait?](https://stackoverflow.com/q/28219730/155423). If you disagree, please [edit] your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Nov 01 '18 at 02:14
  • TL;DR the duplicate: no, you cannot access a field in a generic structure. – Shepmaster Nov 01 '18 at 02:14
  • Okay, edited the question. It's a little different that the trait case, since I need to instantiate a type. – NutellaFan Nov 01 '18 at 03:24
  • Still don't make any sense, please read [ask]. Also, [Writing the perfect question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/) – Stargateur Nov 01 '18 at 03:31
  • 3
    @Shepmaster: My understanding is that the OP is looking for something akin to *pointer-to-member* in C++. That, in C++ you can instantiate a template `MyArray`. – Matthieu M. Nov 01 '18 at 13:41

1 Answers1

3

You can store a getter function for the field you want to access alongside your container, e.g.

pub struct MyVec<A, G> {
    data: Vec<A>,
    getter: G,
}

impl<A, G, T> MyVec<A, G>
where
    G: Fn(&A) -> T,
{
    pub fn get_value(&self, i: usize) -> T {
        (self.getter)(&self.data[i])
    }
}

struct Wobble {
    gloink: u64,
}

impl Wobble {
    fn gloink(&self) -> u64 {
        self.gloink
    }
}

fn main() {
    let v = MyVec {
        data: vec![Wobble { gloink: 42 }],
        getter: Wobble::gloink,
    };
    println!("{}", v.get_value(0));
}

Playground

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841