I have the following program (playground). While the code marked "WORKS" works, using "map" to seems more natural. But I am getting an error when I try that ("cannot return value referencing function parameter info").
How do I use map in such situation or is there another easier way to express the same logic?
struct Info<'a> {
name: &'a str,
}
struct Foo {}
impl Foo {
fn test(&self) {
let info_opt1: Option<Info> = None;
// WORKS:
let _processed_info1 = match info_opt1 {
Some(ref info) => Some(self.process(&info)),
None => None
};
let info_opt2: Option<Info> = None;
// ERROR: returns a value referencing data owned by the current function
let _processed_info2 = info_opt2.map(|info| self.process(&info));
}
fn process<'a>(&self, info: &'a Info<'_>) -> &'a str {
info.name
}
}
The type signature you've written for process is unnecessarily restrictive: as written, if you pass process a &'short Info<'long>, it will return a &'short str, where it could legally return a &'long str. The better signature is
fn process<'a>(&self, info: &Info<'a>) -> &'a str
with which your code compiles.
(Note that for a value of type &'s Info<'t> to exist, 's must be shorter-than-or-equal-to 't, because the inner Info<'t> only lives for 't, and you can't borrow it for longer than that. That's why I'm using the names 'short and 'long, and why the difference between the two signatures is significant.)
@cole-miller It is indeed the case in the snippet here (but I wanted to include a full signature to show the intent). In my original code, it is a lot more involved with multiple reference parameters.