Составные типы данных

Кортежи

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

Кортеж (tuple) представляет способ группировки данных разных типов в один составной тип. Кортежи имеют фиксированный тип в соответствии с вложенными данными. После определения кортежа его размер нельзя ни уменьшить, ни увеличить.

Формальный синтаксис определения кортежа:

let tuple = (значение1, значение2, ... значениеN);

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

Определение простейшего кортежа:

let user = ("Tom", 36, 1.78);

Здесь переменная user представляет кортеж, который состоит из трех элементов.

В примере выше тип элементов кортежа выводится автоматически, но также мы можем явно задать их типы:

let user: (&str, u8, f32) = ("Tom", 36, 1.78);

То есть в данном случае кортеж имеет тип (&str, u8, f32), а это значит, что первый его элемент должен представлять строку, второй элемент - число типа u8, а третий - число с плавающей точкой типа f32.

После объявления кортежа мы можем обращаться к его элементам в виде:

название_кортежа.индек_элемента

После названия кортежа через точку указывается индекс элемента кортежа, при этом индексация начинается с нуля. Например:

fn main(){

	let user: (&str, u8, f32) = ("Tom", 36, 1.78);
	println!("Имя: {}", user.0);	
	println!("Возраст: {}", user.1);
	println!("Рост: {}", user.2);
}

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

Имя: Tom
Возраст: 36
Рост: 1.78

Также мы можем изменять элементы кортежа, если его переменная определена с ключевым словом mut:

fn main(){

	let mut user: (&str, u8, f32) = ("Tom", 36, 1.78);
	user.0 = "Bob";
	println!("Имя: {}", user.0);	// Bob
}

Декомпозиция

Rust предоставляет такую возможность, как декомпозиция (destructuring) кортежа. Например, мы могли бы следующим образом присвоить значения кортежа переменным:

fn main(){

	let user = ("Tom", 36, 1.78);
	// присваиваем переменным значения кортежа
	let name = user.0;
	let age = user.1;
	let height = user.2;

	println!("Имя: {}", name);	
	println!("Возраст: {}", age);
	println!("Рост: {}", height);
}

Но декомпозиция позволяет сократить код:

fn main(){

	let user = ("Tom", 36, 1.78);
	// декомпозиция кортежа на переменные
	let (name, age, height) = user;
	
	println!("Имя: {}", name);	
	println!("Возраст: {}", age);
	println!("Рост: {}", height);
}

Но, возможно, нам нужны не все данные из кортежа. Например, нам не нужно получать рост человека. Тем не менее мы не можем написать, например, так:

let (name, age) = user;	// !Ошибка

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

let (name, age, _) = user;

Сравнение кортежей

Для сравнения кортежей применяется операция ==. Кортежи считаются равными, если равны их соответствующие значения. Пример сравнения кортежа:

fn main() {
 
    let user = ("Tom", 36);
	
	if ("Tom", 36) == user {
        println!("name: Tom, age: 36");
    }
}

Кортеж как параметр и результат функции

Как и любой другой тип, кортеж может выступать параметром функции. Например:

fn display((name, age):(&str, i32)){
	
	println!("name: {}  age:{}", name, age);
}
fn main(){
     
    let tom = ("Tom", 36);
	display(tom);
}

Здесь функции display() принимает кортеж, причем первый элемент этого кортежа представляет тип &str или строку, а второй элемент - тип i32.

И также функция может возвращать кортеж:

fn get_default_point() -> (i32, i32){
	(4, 25)
}
fn main(){
     
    let (x, y) = get_default_point();
	println!("x: {}  y:{}", x, y);
}

Здесь функция get_default_point() возврашает кортеж, первый и второй элементы которого представляют тип i32.

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