4

I guess this is a quite basic Rust question, but I have this piece of code

struct Stock<'a> {
    name: &'a str,
    value: u8,
}
impl<'a> Stock<'a> {
    fn read(file: &mut File) -> Stock<'a> {
        let mut value = vec![0; 1];
        file.read(&mut value);
        let name_size = read_u32(file);
        let mut name = vec![0; name_size as usize];
        file.read(&mut name);
        return Stock {
            name: str::from_utf8(&name).unwrap(),
            value: value[0],
        };
    }
}

and of course, it doesn't work, because I am referencing a local value name. To my limited knowledge, this is because outside the scope of read, name doesn't exist. However wouldn't from_utf8 create a new variable that is not scoped to read?

Also, I've read a bit about other people with this issue, and the suggestion is always to switch to the owned String. But why can't I do something such as name: str::from_utf8(&name).unwrap().to_owned()?

Acorn
  • 24,970
  • 5
  • 40
  • 69
munHunger
  • 2,572
  • 5
  • 34
  • 63
  • 1
    [Here's how you might use `String`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e31965f9a799dc5aca26360538cf630f) (with some other improvements). – trent Sep 19 '20 at 19:48
  • Re: *But why can't I do something such as `name: str::from_utf8(&name).unwrap().to_owned()`?* Yes, and that gives you a `String`. I'm not sure I understand the objection here. Just use `String`. – trent Sep 19 '20 at 19:50
  • The objection is me not yet understanding the language and didn't fully understand that `to_owned` would give me a `String` :) But yeah, I feel like your answers are helping quite a bit (especially the code sample). I just need to fully understand them – munHunger Sep 19 '20 at 20:02

2 Answers2

2

However wouldn't from_utf8 create a new variable that is not scoped to read?

No, it gives you a borrow with the same lifetime as the one you pass.

Even if it created a new variable, you would have to tie it to somewhere, like the scope of read(), so again you would have the same problem.

The issue is that your Stock struct holds a reference. That means whatever it points to it has to live for all the time Stock is alive. But any variables you create in the local scope of read() will die when read() ends.

Instead, what you want is for Stock to own the value so that it keeps alive it itself.

Acorn
  • 24,970
  • 5
  • 40
  • 69
0

You most likely should change the struct field to name: String and get rid of the 'a lifetime parameter.

NovaDenizen
  • 5,089
  • 14
  • 28