Структуры

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

Структуры представляют составной тип данных, который представляет какую-то определенную сущность и который объединяет набор данных, описывающих эту сущность.

Для определения структуры применяется ключевое слово struct:

struct имя_структуры {
	переменная1: тип_данных,
	переменная2: тип_данных,
	.......................
	переменнаяN: тип_данных,
}

После слова struct указывается имя структуры, а затем внутри фигурных скобок через запятую перечисляются ее переменные. Переменные структуры еще называются полями. Для каждого поля определяется название и его тип.

Например, определение простейшей структуры:

struct Person	// структура - человек
{
    name: String,	// имя
	age: u8,		// возраст
	height: f32		// рост
}

В данном случае определена структура Person, которая представляет сущность "человек". Названия структур обычно начинаются с большой буквы. Эта структура имеет три поля, которые описывают соответственно имя, возраст и рост человек.

Обратите внимание, что имя человека - поле name представляет тип String, который представляет расширяемую строку и который также является встроенной в Rust структурой. Таким образом, одни структуры могут быть полями других структур.

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

let tom = Person{
	name: "Tom".to_string(),
	age: 36,
	height: 1.78
};

Здесь обращаю внимание, что значение для поля указывается после двоеточия (:), а не после знака равно, как при обычном присвоении. Кроме того, полю name присваивается не просто строка "Tom", а результат метода "Tom".to_string(), который преобразует строковый литерал к типу String.

Затем через имя переменной структуры мы сможем обращаться к ее полям:

название_переменной.поле_структуры

После названия переменной через точку указывается поле структуры.

Например, используем вышеописанную структуру в программе:

fn main(){
     
    let tom = Person{
		name: "Tom".to_string(),
		age: 36,
		height: 1.78
	};
	
    println!("name = {}", tom.name);
    println!("age = {}", tom.age);
    println!("height = {}", tom.height);
}
struct Person	// структура - человек
{
    name: String,	// имя
	age: u8,		// возраст
	height: f32		// рост
}

Консольный вывод программы:

name = Tom
age = 36
height = 1.78

Если мы хотим изменять значения полей структуры, то переменная структуры должна быть определена с ключевым словом mut:

fn main(){
     
    let mut tom = Person{
		name: "Tom".to_string(),
		age: 36,
		height: 1.78
	};
    println!("name={}  age = {} height={}", tom.name, tom.age, tom.height);
	// меняем значения полей
	tom.age = 25;
	tom.height = 1.81;
    println!("name={}  age = {} height={}", tom.name, tom.age, tom.height);
}
struct Person	// структура - человек
{
    name: String,	// имя
	age: u8,		// возраст
	height: f32		// рост
}

Консольный вывод:

name = Tom  age = 36  height = 1.78
name = Tom  age = 25  height = 1.81

Передача значений по имени

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

fn main(){
     
	let age = 22;
	let height = 1.68;
    let tom = Person{
		name: "Tom".to_string(),
		age,
		height
	};
    println!("name={}  age = {} height={}", tom.name, tom.age, tom.height);
}
struct Person
{
    name: String,
	age: u8,	
	height: f32	
}

Здесь названия переменных age и height совпадает с названиями полей. Поэтому вместо

let age = 22;
let height = 1.68;

let tom = Person{
	name: "Tom".to_string(),
	age: age,
	height: height
};

Можно написать:

let age = 22;
let height = 1.68;

let tom = Person{
	name: "Tom".to_string(),
	age,
	height
};

Передача значений из другой структуры

Иногда возникает необходимость передать одной переменной структуры при инициализации значения другой переменной этой структуры. И тут Rust тоже позволяет сократить код:

fn main(){
     
	let bob = Person{
		name: "Bob".to_string(),
		age: 33,
		height: 1.70
	};
    let tom = Person{
		name: "Tom".to_string(),
		..bob
	};
    println!("name={}  age = {} height={}", tom.name, tom.age, tom.height);
}
struct Person
{
    name: String,
	age: u8,	
	height: f32	
}

Выражение ..bob указывает, что переменная структуры будет наполняться из переменной bob. Если мы хотим для отдельных полей определить другие значения, то мы можем их прописать явно:

let tom = Person{
	name: "Tom".to_string(),
	..bob
};

В данном случае переменная tom берет из переменной bob значения для полей age и height, а для поля name определяет свое значение.

Декомпозиция структуры

Rust позволяет раскладывать структуры на переменные. Для этого применяется оператор let:

let структура{поле_структуры: переменная} = объект_структуры;

Рассмотрим пример с декомпозицией структуры Person:

struct Person
{
    name: String,
	age: u8,	
	height: f32	
}
fn main(){
     
	let tom = Person{
		name: "Tom".to_string(),
		age: 33,
		height: 1.70
	};
	let Person{name: username, age: userage, height: _} = tom;
    println!("name = {}  age = {}", username, userage);
}

Здесь выражение

let Person{name: username, age: userage, height: _} = tom;

указывает, что из структуры tom значение поля name надо передать в переменную username, а значение поля age - в переменную userage. Переменные username и userage определяются автоматически. А поле height, к примеру, мы не хотим использовать, поэтому ему передается прочерк _.

И далее мы сможем использовать переменные username и userage.

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