Reference another struct member in new

Hello,

I'm trying to figure out how I can set a reference to another struct member's data during instantiation. This code compiles and has the correct outcome of referencing the first element of the member array:

struct Foo<'a> {
    tokens:Vec<i32>,
    current_tok:Option<&'a i32>,
}

impl<'a> Foo<'a> {
    fn new(tokens:Vec<i32>) -> Foo<'a> {
        Foo {
            tokens,
            current_tok: None,
        }
    }
}

fn main() {

    let mut foo = Foo::new(vec![1,2,5]);
    foo.current_tok = foo.tokens.first();

    match foo.tokens.first() {
        Some(x) => println!("{}",x),
        _ => {},
    }

}

See Playground.

I would like to be able to do this in the new function something like this:


struct Foo<'a> {
    tokens:Vec<i32>,
    current_tok:Option<&'a i32>,
}

impl<'a> Foo<'a> {
    fn new(tokens:Vec<i32>) -> Foo<'a> {
        Foo {
            tokens,
            current_tok: tokens.first(),
        }
    }
}

fn main() {

    let foo = Foo::new(vec![1,2,5]);
//  Not assigning here >>>
//  foo.current_tok = foo.tokens.first();

    match foo.tokens.first() {
        Some(x) => println!("{}",x),
        _ => {},
    }
}

See Playground

I am aware enough of the borrowing rules to understand the problem but not well enough to come up w/ a solution :).

Thanks for any help.

You cannot safely make a struct that refers to itself, which is what you are trying to do. The simplest thing to do is just use an index for current_tok.

EDIT: I see there's probably some confusion about why your first example compiles. It compiles because you're not using foo. If you try to do anything with it you'll get error[E0505]: cannot move out of `foo` because it is borrowed. That is why you can't move it out of new: you're borrowing it by assigning a reference to it, and you can only do that as long is you don't move foo anywhere while the reference exists.

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.