I have a function tk_from_file
that reads a file, and returns a struct Tokenizer
, with a Peekable<Chars<'a>>
over the contents of that file.
The variable content
is from the Result<String>
returned from std::fs::read_to_string
However, when I try to create the struct and return it, I get the following error (E0515):
30 | return Tokenizer {
| ________________^
31 | | content: content.clone().chars().peekable(),
| | --------------- temporary value created here
32 | | loc: FileLocation {
33 | | file: path,
... |
36 | | }
37 | | };
| |_________^ returns a value referencing data owned by the current function
I have tried using it with clone()
and without, as well as clone()
on the Chars iterator in addition to the String, but it still doesn't work.
CodePudding user response:
It doesn't matter if you clone
this String
or not. String
created in this function is owned by this function, therefore you cannot return any references to it from the function, because when the stack frame of the function is popped the String
will be dealocated and you will have a dangling pointer, which is a big no no in rust world.
If you want to reference this String
created when reading file you must return owned String
from the function somehow and give an ownership of it to the caller. One solution would be to store a String
inside Tokenizer
struct and provide a method on it that would borrow a String
and return iterator.
struct Tokenizer {
content: String,
...
}
impl Tokenizer {
fn content(&self) -> Peekable<Chars<'_>> {
self.content.chars().peekable()
}
}
With following structure you can pass ownership of file content to the caller and allow them to borrow it for as long as they want. You can read more about ownership and borrowing in this chapter of The Book.