ArekBulski
ArekBulski

Reputation: 5088

Rust: returns a value referencing data owned by the current function

I have this little piece of snippet of code. Why does the 2nd fail to compile?

fn apply (&self, text: Text) -> Text {
    // works fine
    let mut data = String::new();
    for c in text.data.chars() {
        let c = *self.mapping.get(&c).unwrap_or(&c);
        data.push(c);
    }
    return Text {
        data,
    };

    // not compile
    return Text {
        data: text.data.chars().map(|c| self.mapping.get(&c).unwrap_or(&c)).collect(),
    };
}

Upvotes: 0

Views: 2412

Answers (1)

Masklinn
Masklinn

Reputation: 42282

The comppiler tells you exacly why (which is why reading and posting compilation errors is useful:

8 |             data: text.data.chars().map(|c| self.mapping.get(&c).unwrap_or(&c)).collect()
  |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--^
  |                                             |                              |
  |                                             |                              `c` is borrowed here
  |                                             returns a value referencing data owned by the current function

In the case where the input char is not present in the mapping, it returns a reference to a local variable which is not allowed as... the reference would then be left dangling, something rust does not allow.

The solution is the exact same as that used in the "works fine" version: dereference the callback's result, which will Copy the &char to a char, which is owned and can thus be returned with no lifetime concerns:

        Text {
            data: text.data.chars().map(|c| *self.mapping.get(&c).unwrap_or(&c)).collect()
        }

Alternatively you could copied the result of HashMap::get yielding an Option<char>, which would then be unwrap_or'd to char, fixing the issue for the same reasons:

        Text {
            data: text.data.chars().map(|c| self.mapping.get(&c).copied().unwrap_or(c)).collect()
        }

Upvotes: 1

Related Questions