Reputation: 530
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
Reputation: 431069
The function that ended up functioning as intended:
fn reverse_string(input: &str) -> String {
input.chars().rev().collect()
}
Upvotes: 0
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:
input.chars().rev().collect()
for exampleinput
in-place, which requires it to be mut
of courseThe 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