Если структура имеет поля, которые хранят ссылки, то при определении методов потребуется использовать аннотации времени жизни для ссылок.
Формальное применение аннотаций времени жизни в определении метода:
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 }