How to pass a field name of a struct to a method of that struct?

Hi!

I have a struct with different fields and a method of that struct that performs the same logic but for different fields. The caller of this method shall be able to dertermine the field on which the method should act.

#[derive(Default)]
struct Test {
    field_a: Vec<u16>,
    field_b: Vec<u16>,
}

impl Test {
    pub fn do_something(&mut self, add: u16, field: <field_a or field_b>) {
        &self.field.push(add);
    }
}

fn main() {
    let mut test: Test = Default::default();
    test.do_something(5,<field_b>);
}

How can this be achieved?

Thank you!

Regards,
Ted

I'd use a plain vanilla enum for that:

#[derive(Default)]
struct Test {
    field_a: Vec<u16>,
    field_b: Vec<u16>,
}

impl Test {
    pub fn do_something(&mut self, add: u16, field: Field) {
        match field {
            Field::A => self.field_a.push(add),
            Field::B => self.field_b.push(add),
        }
    }
}

enum Field {
    A,
    B,
}

fn main() {
    let mut test: Test = Default::default();
    test.do_something(5, Field::B);
}

Playground.

1 Like

Or… why not just pass a mutable reference to the field?

impl Test {
    pub fn do_something(add: u16, field: &mut Vec<u16>) {
        field.push(add);
    }
}

fn main() {
    let mut test: Test = Default::default();
    Test::do_something(5, &mut test.field_b);
}
3 Likes

Thanks guys!

@H2CO3 This solution is so obvious that I think I need to take a break... ideal example for "to miss the forest for the trees" :smiley:

But while we're on it: How would you do this if the struct looks like this?

struct Test {
   field_a: Vec<u16>,
   field_b: Vec<String>,
   field_c: Vec<f64>,
}

Then the method would need to be generic also with the parameter "add".

Thanks again!

fn do_something<T>(add: T, field: &mut Vec<T>)

?

3 Likes

Thank you... It seems that I am a little confused at the moment :man_facepalming:

Also, at that point it's literally just Vec::push(), so you wouldn't need a separate method.

1 Like

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.