Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I return a reversed string from a function?

Tags:

rust

lifetime

I want to write a function that would reverse a string and return a reference to the returned string. I thought I would be able to specify that the returned reference has the same lifetime as the provided reference.

fn reverse_string<'a>(input: &'a str) -> &'a str {
    let res: &'a str = input.chars().rev().collect().as_slice();
    res
}

This was my attempt, and I receive the error:

error[E0282]: type annotations needed
 --> src/lib.rs:2:24
  |
2 |     let res: &'a str = input.chars().rev().collect().as_slice();
  |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `B`
  |
  = note: type must be known at this point

I thought the type specification would resolve this. Lifetimes are a bit confusing to me, so I was hoping someone may be able to explain how to do this properly, or if I'm completely off base to begin with.

like image 888
Alex P Avatar asked Dec 09 '25 07:12

Alex P


1 Answers

The lifetime issue is similar to The lifetime of &str makes comparison hard: if you create a new object, it's a new object, uncorrelated from the old one.

Therefore, you have two choices:

  • either create a completely new object: input.chars().rev().collect() for example
  • or reverse the input in-place, which requires it to be mut of course

The former looks easy:

fn reverse_new(input: &str) -> String {
    input.chars().rev().collect()
}

however the String so created might be "flawed", because char (the intermediate type) are just Unicode code points not graphemes. As an example of Combining Characters imagine that you have [e, ́, o] in the original string, the ́ is attached to the e: éo, but after reversal you get [o, ́, e] where ́ is attached to the o: óe.

The latter is severely complicated by the fact that even ignoring graphemes issues, reversing UTF-8 in-place requires being UTF-8 aware to avoid splitting codepoints. Of course, one could simply create a reversed String and copy it into the input...

EDIT: I had initially thought of collecting into an intermediary Vec, but @AlexP realized it was unnecessary and one could collect directly into a String.

like image 126
Matthieu M. Avatar answered Dec 12 '25 01:12

Matthieu M.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!