Alex P
Alex P

Reputation: 530

How do I return a reversed string from a function?

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.

Upvotes: 3

Views: 3406

Answers (2)

Shepmaster
Shepmaster

Reputation: 431069

The function that ended up functioning as intended:

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

Upvotes: 0

Matthieu M.
Matthieu M.

Reputation: 299960

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.

Upvotes: 8

Related Questions