0

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(), }; } 
1
  • Could you include the compiler error in the question, and/or provide a stand-alone example that we can try? Commented Apr 14, 2021 at 6:58

1 Answer 1

1

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() } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.