Если структура имеет поля, которые хранят ссылки, то при определении методов потребуется использовать аннотации времени жизни для ссылок.
Формальное применение аннотаций времени жизни в определении метода:
impl<'a> структра<'a> {
fn метод(&self){
}
}
Вначале посмотрим, что будет если мы не используем аннотации в определении метода:
struct Person<'a> {
name: &'a str,
}
impl Person{
fn print(&self){
println!("Имя пользователя: {}", self.name);
}
}
fn main() {
let tom= Person { name: "Tom"};
tom.print();
}
Здесь для структуры Person, которая применяет аннотацию для ссылки, определен метод print(). Однако при определении метода не применяется
никаких аннотаций, поэтому мы получим ошибку при компиляции:
Теперь применим аннотации в определении метода:
struct Person<'a> {
name: &'a str,
}
impl<'a> Person<'a>{
fn print(&self){
println!("Имя пользователя: {}", self.name);
}
}
fn main() {
let tom= Person { name: "Tom"};
tom.print(); // Имя пользователя: Tom
}
Теперь ошибки не возникнет, и программа будет прекрасно работать.
Кроме того, параметры и результаты методы могут использовать свои аннотации:
struct Person<'a> {
name: &'a str,
}
impl<'a> Person<'a>{
fn say<'b>(&self, words: &'b str) -> &'b str{
println!("{} говорит: {}", self.name, words);
words
}
}
fn main() {
let tom= Person { name: "Tom"};
tom.say("Hello");
}
По умолчанию в методах время возвращаемой ссылки соответствует времени жизни объекта структуры, который вызвал метод и который передается в метод через параметр
&self, однако в данном случае для возвращения результата применяется другой параметр-ссылка - строковый слайс words.
К параметру words и возвращаемой ссылке применяется аннотация 'b, которая устанавливает, как и в случае с обычными функциями, что время жизни возвращаемой ссылки
соответствует времени жизни объекта из параметра words. Причем в таком случае время жизни возвращаемой ссылки может быть большим, чем у объекта Person,
который будет вызывать метод:
struct Person<'a> {
name: &'a str,
}
impl<'a> Person<'a>{
fn say<'b>(&self, words: &'b str) -> &'b str{
println!("{} говорит: {}", self.name, words);
words
}
}
fn main() {
let speech = String::from("Hello");
let tom_saying;
{
let tom= Person { name: "Tom"};
tom_saying = tom.say(speech.as_str());
} // конец жизни объекта tom
println!("{}", tom_saying); // ссылку tom_saying по прежнему можно использовать
}
Однако если метод возвращает ссылку на основе поля из структуры, в этом случае аннотации можно не использовать, поскольку возвращаемая ссылка автоматически будет иметь соответствовать времени жизни объекта структуры:
struct Person<'a> {
name: &'a str,
}
impl<'a> Person<'a>{
fn say(&self, words: &str) -> &str{
println!("{} говорит: {}", self.name, words);
self.name
}
}
fn main() {
let speech = String::from("Hello");
{
let tom= Person { name: "Tom"};
let tom_saying = tom.say(speech.as_str());
println!("{}", tom_saying);
} // конец жизни объекта tom и ссылки tom_saying
}