Аннотации ссылок в определениях методов

Последнее обновление: 26.04.2021

Если структура имеет поля, которые хранят ссылки, то при определении методов потребуется использовать аннотации времени жизни для ссылок.

Формальное применение аннотаций времени жизни в определении метода:

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(). Однако при определении метода не применяется никаких аннотаций, поэтому мы получим ошибку при компиляции:

reference lifetime annotation in method in Rust

Теперь применим аннотации в определении метода:

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
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850