Аннотации ссылок в структурах

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

Подобно тому, как аннотации времени жизни применяются в функциях, они также могут применяться в структурах. Формальное применение аннотаций:

struct название_структуры<'аннотация> {
    поле_структуры: &'аннотация str,
}

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

Сначала рассмотрим проблему, с которой мы можем столкнуться. Пусть у нас есть структура, поле которой представляет строковый слайс, то есть ссылку:

struct Person {
    name: &str,
}

fn main() {
    let tom = Person { name: "Tom" };
	println!("{}", tom.name);
}

Но при компиляции компилятор Rust укажет, что необходимо установить аннотации времени жизни для поля name в структуре Person:

reference lifetime in struct in Rust

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

struct Person<'a> {
    name: &'a str,
}

fn main() {
    let tom = Person { name: "Tom" };
	println!("{}", tom.name);	// Tom
}

Здесь структура применяет аннотацию 'a. Применение аннотации означает, что объект структуры будет доступен пока доступна ссылка из поля name. Что это значит? Рассмотрим следующий пример:

struct Person<'a> {
    name: &'a str,
}

fn main() {

	let mut tom;
	{
		let username = String::from("Tom");
		tom = Person { name: username.as_str()};
		println!("{}", tom.name);
	}
	tom.name = "Sam";
	println!("{}", tom.name);
}

Здесь переменная tom определена с ключевым словом mut, чтобы теоретически можно было поменять значения ее полей.

Во вложенном блоке кода создается объект username, который представляет тип String. То есть время жизни этого объекта ограничено вложенным блоком кода.

Далее полю name объекта структуры присваивается строковый слайс, полученный с помощью метода as_str() из объекта username.

tom = Person { name: username.as_str()};

После завершения вложенного блока кода мы пытаемся изменить значения поля name - переменная tom же определена как изменяемая. Однако проблема в том, что мы не можем использовать объект Person, представленный переменной tom, вне области видимости переменной username. Соответственно при компиляции мы получим ошибку:

время жизни ссылки в структурах в Rust

Мы могли бы исправать ситуацию, перенеся весь код использования объекта tom в область видимости переменной username:

struct Person<'a> {
    name: &'a str,
}

fn main() {

	let mut tom;
	{
		let username = String::from("Tom");
		tom = Person { name: username.as_str()};
		println!("{}", tom.name);	// Tom
		tom.name = "Sam";
		println!("{}", tom.name);	// Sam
	}
}

Либо создать новый объект структуры Person и присвоить его переменной tom:

struct Person<'a> {
    name: &'a str,
}

fn main() {

	let mut tom;
	{
		let username = String::from("Tom");
		tom = Person { name: username.as_str()};
		println!("{}", tom.name);
	}
	tom = Person { name: "Sam"};
	println!("{}", tom.name);
}

Правда, в данном случае мы уже будем работать с уже другим объектом.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850