behai
October 27, 2023, 1:44pm
1
Hi,
I have difficulties understanding an example given in this page Tour of Rust's Standard Library Traits | Generic Parameters .
I'm reproducing the code below, with some println!
, and fn main()
added:
// trait declaration generalized with lifetime & type parameters
trait Trait<'a, T> {
// signature uses generic type
fn func1(arg: T);
// signature uses lifetime
fn func2(arg: &'a i32);
// signature uses generic type & lifetime
fn func3(arg: &'a T);
}
struct SomeType;
// Mine.
impl SomeType {
fn print_me(self) {
println!("I am struct SomeType.fn print_me(self).");
}
}
impl<'a> Trait<'a, i8> for SomeType {
fn func1(arg: i8) { println!("func1 a i8 {}", arg); }
fn func2(arg: &'a i32) { println!("func2 lifetime a i32 {}", arg); }
fn func3(arg: &'a i8) { println!("func3 lifetime a i8 {}", arg); }
}
impl<'b> Trait<'b, u8> for SomeType {
fn func1(arg: u8) { println!("func1 b u8 {}", arg); }
fn func2(arg: &'b i32) { println!("func2 lifetime b i32 {}", arg); }
fn func3(arg: &'b u8) { println!("func3 lifetime b u8 {}", arg); }
}
fn main() {
<SomeType as Trait<i8>>::func1(34);
<SomeType as Trait<i8>>::func2(&34);
<SomeType as Trait<i8>>::func3(&34);
<SomeType as Trait<u8>>::func1(34);
<SomeType as Trait<u8>>::func2(&34);
<SomeType as Trait<u8>>::func3(&34);
}
Please help with the following questions:
Question ❶
In fn main()
, am I call the trait methods correctly, please?
Question ❷
If I WAS calling them correctly, then what were the lifetime annotations 'a
and 'b
for, please?
I understand that The Book states:
We must only annotate types when multiple types are possible. In a similar way, we must annotate lifetimes when the lifetimes of references could be related in a few different ways. Rust requires us to annotate the relationships using generic lifetime parameters to ensure the actual references used at runtime will definitely be valid.
Is it in anyway related to the above quote, please?
Thank you and best regards,
...behai.
H2CO3
October 27, 2023, 1:55pm
2
"Correctly" in what sense? The code you posted compiles, but you could readily verify that for yourself by pasting it into the Playground .
They denote the validity of the references being passed, just like in any other case. I don't understand what specifically you are looking for here.
1 Like
vague
October 27, 2023, 1:56pm
3
Yes, because your code compiles fine.
Absolutely related. And that quote is definitely the seriously underestimated prior knowledge to understand lifetime annotations.
In your case, 'a or 'b is a plain lifetime with no interaction with any other lifetimes, so it's trivially means a given lifetime from a borrow.
1 Like
behai
October 27, 2023, 10:48pm
4
vague:
Absolutely related. And that quote is definitely the seriously underestimated prior knowledge to understand lifetime annotations.
In your case, 'a or 'b is a plain lifetime with no interaction with any other lifetimes, so it's trivially means a given lifetime from a borrow.
Good morning vague,
Thank you for the explanation. I appreciate it.
Best regards,
...behai.
behai
October 27, 2023, 11:00pm
5
H2CO3:
"Correctly" in what sense? The code you posted compiles, but you could readily verify that for yourself by pasting it into the Playground .
They denote the validity of the references being passed, just like in any other case. I don't understand what specifically you are looking for here.
Good morning H2CO3,
Thank you for helping me...
"Correctly" in what sense? -- I did think about this when posting the question, I don't remember seeing the as
keyword before, <SomeType as Trait>
is from this Stackoverflow answer, I was expecting the compiler gives error about the lifetime and the generic type, but it only suggests adding <i8>
(and <u8>
). The code is not mine, it compiles and works as expected. That is the reason why I am uncertain and decided to ask for help.
I don't understand what specifically you are looking for here. -- it is related to the uncertainty I have above, I was expecting (wrongly) the compiler complains about lifetime, but it does not. Obviously, I still don't fully get lifetime yet... but I will.
Best regards,
...behai.
H2CO3
October 28, 2023, 5:59am
6
Google "lifetime elision".
1 Like
behai
October 28, 2023, 11:22am
7
Thank you. I will. I have seen that in "The Book" -- but I will study it again.
Best regards,
...behai.
behai
October 31, 2023, 11:13pm
8
Hi,
On lifetime elision , for info, if new readers happen to find this thread in the future.
"The Book", Chapter 10 | Generic Types, Traits, and Lifetimes last section https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html , explains lifetimes, I did not get it the first time round, now that I went back and re-read, it helps enourmously.
-- Especially the three rules.
I think I understand lifetime elision a bit better now And I can exercise the last example longest_with_an_announcement
, too:
use std::fmt;
fn longest_with_an_announcement<'a, T>(
x: &'a str,
y: &'a str,
ann: T,
) -> &'a str
where
T: fmt::Display,
{
println!("Announcement! {}", ann);
if x.len() > y.len() {
x
} else {
y
}
}
struct BeHai<'a> {
text: &'a str,
}
impl<'a> fmt::Display for BeHai<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "BeHai.text <{}>", &self.text)
}
}
fn main() {
let novel = String::from("Call me Ishmael. Some years ago...");
let reader = String::from("John");
let res = longest_with_an_announcement::<BeHai>(
&reader.as_str(),
&novel.as_str(),
BeHai{text: String::from("asking too many questions").as_str()}
);
println!("res {}", res);
}
Best regards,
...behai.