I have struct
struct Cursor<'a> {
chars: Chars<'a>,
}
what's the difference between
impl Cursor<'_> {
fn new(input: &str) -> Cursor { ... }
}
and
impl<'a> Cursor<'a> {
fn new(input: &'a str) -> Cursor<'a> { ... }
}
?
I have struct
struct Cursor<'a> {
chars: Chars<'a>,
}
what's the difference between
impl Cursor<'_> {
fn new(input: &str) -> Cursor { ... }
}
and
impl<'a> Cursor<'a> {
fn new(input: &'a str) -> Cursor<'a> { ... }
}
?
The difference is that the first version is desugared as:
impl<'a> Cursor<'a> {
fn new<'b>(input: &'b str) -> Cursor<'b> { ... }
}
That is, there are two distinct lifetimes.
However, I'm having hard time imagining any actual difference. The compiler will just infer to 'a to be some lifetime, and you'll work only with 'b, just like you work with 'a in the second version.
It's to do with lifetime elision. To quote The Edition Guide:
Rust 2018 allows you to explicitly mark where a lifetime is elided, for types where this elision might otherwise be unclear. To do this, you can use the special lifetime
'_much like you can explicitly mark that a type is inferred with the syntaxlet x: _ = ..;.Let's say, for whatever reason, that we have a simple wrapper around
&'a str:struct StrWrap<'a>(&'a str);In Rust 2015, you might have written:
use std::fmt; fn make_wrapper(string: &str) -> StrWrap { StrWrap(string) } impl<'a> fmt::Debug for StrWrap<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.write_str(self.0) } }In Rust 2018, you can instead write:
fn make_wrapper(string: &str) -> StrWrap<'_> { StrWrap(string) } impl fmt::Debug for StrWrap<'_> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.write_str(self.0) } }